Pie[二分]

来源:互联网 发布:保险退保现金价值算法 编辑:程序博客网 时间:2024/06/13 02:13

题意:过生日大家分饼吃?m+1个人分饼,每个人要分一样的面积(高度为1),饼可以切但是不能拼。问最大能人均多少。
思路:二分面积就好啦。先算出每个饼的面积,由于check需要O(n)复杂度,所以套一层二分面积就好。
二分的单调性: 如果能够均分每人得到S的饼,那么对于任意的Si<S都满足能够分得。
二分的 check(mid):对于给定的均分量mid,看每个饼能出几份,然后加起来看是否大于等于m+1即可。

#include<iostream>#include<string>#include<cstdio>#include<cstring>#include<bitset>#include<algorithm>#include<map>#include<set>#include<queue>#include<vector>#include<cstdlib>#include<list>#include<stack>#include<cmath>#include<iomanip>using namespace std;//#pragma comment(linker, "/STACK:1024000000,1024000000")typedef long long LL;void debug() {cout << "ok running!" << endl;}const double PI = acos(-1.0);int n, m;double a[10005];bool check(double x){    int sum = 0;    for(int i = 0; i < n; ++i)        sum += (int)(a[i]/x);    if(sum >= m)        return 1;    else return 0;}int main(){    ios::sync_with_stdio(false);    #ifndef ONLINE_JUDGE    freopen("input.txt", "r", stdin);    #endif // ONLINE_JUDGE    int t;    cin >> t;    while(t--)    {        cin >> n >> m;        m++;        for(int i = 0; i < n; ++i)        {             int x;             cin >> x;             a[i] = x*x*PI;        }        //cout << a[0] << endl;        double l = 0, r = 10005*10005*PI;        double ans = -1;        while(r - l > 0.000001)        {            //cout << l << " " << r << endl;            double mid = (l+r)/2;            //cout << mid << endl;            if(check(mid))            {                ans = mid;                l = mid;            }            else r = mid;        }        ios::fixed;        //cout << ans << endl;        cout << fixed << setprecision(4) << ans << endl;    }    return 0;}
原创粉丝点击