先按从大到小排序,二分,check的思路是这样的:
a选了i个,然后判断b至少要选几个(代码中的ans),用了二分。 再根据ans代入a中判断是否可行。
提前将所有浮点数*10000了。
# include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
# define int long long
int n;
int a[N],b[N];
bool compare(const int &x,const int &y) {return x > y;}
bool check(double mid)
{
// bool flag = (mid == 16000);
for(int i = 1; i <= n; i++)
{
int l = 1, r = n,ans = n + 1;
while(l <= r)
{
int mid2 = (l + r) >> 1;
if(b[mid2] >= i * 10000 + mid) {r = mid2 - 1,ans = mid2;}
else l = mid2 + 1;
}
// if(flag) printf("i = %d,ans = %d\n",i,ans);
if(a[i] - ans * 10000 >= mid) return 1;
}
return 0;
}
signed main(void)
{
scanf("%lld",&n);
for(int i = 1; i <= n; i++)
{
double x,y;
cin >> x >> y;
a[i] = x * 10000,b[i] = y * 10000;
}
sort(a + 1, a + n + 1, compare),sort(b + 1, b + n + 1, compare);
for(int i = 1; i <= n; i++) a[i] -= 10000,b[i] -= 10000;
for(int i = 1; i <= n; i++) a[i] += a[i - 1],b[i] += b[i - 1];
int l = 0,r = 1e12,ans = 1145141919810;
while(l <= r)
{
int mid = (l + r) >> 1;
if(check(mid)) {l = mid + 1; ans = mid;}
else r = mid - 1;
}
printf("%.4lf\n",double(ans) / 10000.0);
return 0;
}