求救
查看原帖
求救
153546
luyiming楼主2021/7/20 20:19

先按从大到小排序,二分,check的思路是这样的:

aa选了ii个,然后判断bb至少要选几个(代码中的ansans),用了二分。 再根据ansans代入aa中判断是否可行。

提前将所有浮点数*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;
}
2021/7/20 20:19
加载中...