P10091 [ROIR 2022 Day 2] 分数排序 题解
题目大意
题目传送门 (翻译自 ROIR 2022 D2T2)
给定
输出格式:若要输出 a b 。
思路
先将
排序后不难得出,check。当然精度得够高,在这里我们使用 long double 来操作。
那么二分出来的值如何匹配上正确的分母和分子呢?我们可以挨个儿去试,看看每个 round 函数进行四舍五入(具体用法看这里,此题解默认你们会用)。
参考代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5 , AB = 1e6+5;
long long n,Q,a[N],b[N],q,p,g;
long double l,r;
bool v[AB];
bool check(long double k){
long long j=0,sum=0;
for(int i=1;i<=n;i++){
while((long double)a[j+1]<(long double)k*b[i]&&j<n)j++;
sum+=j;
}
return sum>=q;
}
long long gcd(long long x,long long y)
{
if(x<y)swap(x,y);
if(y==1)return y;
if(x%y==0)return y;
else return gcd(y,x%y);
}
int main(){
scanf("%lld%lld",&n,&Q);
for(int i=1;i<=n;i++){scanf("%lld",&a[i]);v[a[i]]=1;}
for(int i=1;i<=n;i++)scanf("%lld",&b[i]);
sort(a+1,a+n+1);
sort(b+1,b+n+1);
while(Q--){
scanf("%lld",&q);
l=(long double)a[1]/b[n];r=(long double)a[n]/b[1];
while(r-l>=1e-13){
long double mid=(l+r)/2;
if(check(mid))r=mid;
else l=mid;
}
for(int i=1;i<=n;i++){
p=round(l*b[i]);
if(p<=1e6&&v[p]&&abs(p-l*b[i])<1e-7){
g=gcd(p,b[i]);
printf("%lld %lld\n",p/g,b[i]/g);
break;
}
}
}
return 0;
}
注:此代码已 AC,可放心看,但请不要直接提交我的代码。