努力ing
你浪费的今天是昨天死去的人所渴望的明天!!!
http://acm.hdu.edu.cn/showproblem.php?pid=1969
自己纠结了很久,然后参考别人代码才知道,要学以致用啊!
http://www.cnblogs.com/newpanderking/archive/2011/08/24/2152576.html
题目大意是要办生日Party,有n个馅饼,有f个朋友,接下来是n个馅饼的半径。然后是分馅饼了,
注意咯自己也要,大家都要一样大,形状没什么要求,但都要是一整块的那种,也就是说不能从两个饼中 各割一小块来凑一块,像面积为10的和6的两块饼(饼的厚度是1,所以面积和体积相等), 如果每人分到面积为5,则10分两块,6切成5,够分3个人,如果每人6,则只能分两个了! 题目要求我们分到的饼尽可能的大!

只要注意精度问题就可以了,一般WA 都是精度问题
运用2分搜索:
首先用总饼的体积除以总人数,得到每个人最大可以得到的V,但是每个人手中不能有两片或多片拼成的一块饼,
最多只能有一片分割过得饼。用2分搜索时,把0设为left,把V 设为right。mid=(left+right)/2;
搜索条件是:以mid为标志,如果每块饼都可以分割出一个mid,那么返回true,说明每个人可以得到的饼的体积可以
大于等于mid;如果不能分出这么多的mid,那么返回false,说明每个人可以得到饼的体积小于等于mid。
(1)精度为:0.000001
(2)   pi 用反余弦求出,精度更高。
#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;
double pi=acos(-1.0);
double v[10001];

double mid;
int f,n;
bool test(double x)
{
    int i;
    int num=0;
    for(i=0;i<n;i++)
    {
        num+=(int )(v[i]/x);
    }
    if(num>=f) return true;
    else return false;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int i,r;
        double V=0,start,end;
        cin>>n>>f;
        f=f+1;
        for(i=0;i<n;i++)
        {
            cin>>r;
            v[i]=pi*r*r;
            V+=v[i];
        }
    //    cout<<f<<endl;
        V=V/f;
        start=0.0;
        end=V;
        while((end-start)>1e-6)
        {
            mid=(start+end)/2;
            if(test(mid))
                start=mid;
            else end=mid;
        }
        cout<<setiosflags(ios::fixed)<<setprecision(4)<<mid<<endl;
    }
    return 0;
}

 

 

posted on 2013-05-08 22:23  努力ing  阅读(144)  评论(0)    收藏  举报