POJ 3312 (二分)

看题传送门~~http://poj.org/problem?id=3122

Pie
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 21286   Accepted: 6829   Special Judge

Description

My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though. 

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size. 

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.

Input

One line with a positive integer: the number of test cases. Then for each test case:
  • One line with two integers N and F with 1 ≤ N, F ≤ 10 000: the number of pies and the number of friends.
  • One line with N integers ri with 1 ≤ ri ≤ 10 000: the radii of the pies.

Output

For each test case, output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number with an absolute error of at most 10 −3.

Sample Input

3
3 3
4 3 3
1 24
5
10 5
1 4 2 3 4 5 6 5 4 2

Sample Output

25.1327
3.1416
50.2655


    这个题算是水题,算法思想并不难,就是二分查找答案,要注意的一点是每一个人分到的派必须是整个的,不能是由几个不完整的拼凑起来的。

    易错的几点是1. 每个人分到的派的半径不一定是整数,也可以是小数。2. 这个题可以先用半径的平方进行计算,随后再乘以PI。3.这个题如果算法过程没错却WA,可以考虑是精度出了问题,改一改精度说不定能过。

    下面上一波C艹实现

#include <iostream> // POJ居然不支持万能头
#include <cstdio>
#include <vector>
#define PI  3.14159265359 //这个PI的精度最好开的高一点,否则无限WA,血泪教训
using namespace std;
vector<int> pie;

double fun(double l, double r, int f){

    while(l + 0.0000001 < r){   //0.0000001就是二分精度,懒得一批没写在开头
        double mid = (l + r) / 2;
        int cnt = 0;
        for(int i = 0;i < (int)pie.size();++i){
            cnt += (pie[i] / mid);
        }
        if(cnt <= f)  //要注意这里是小于等于,使得最后分界点以左的都是正好可以满足题意的。
            r = mid;
        else
            l = mid;
    }
    return l;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    int nCase;
    scanf("%d",&nCase);
    for(int i= 0;i < nCase;++i){
        int n, f;
        double temp = 0;
        scanf("%d %d",&n, &f);

        for(int j = 0; j < n;++j){
            int x;
            scanf("%d",&x);
            pie.push_back(x * x);
            temp += x * x;
        }
        temp /= f;  //这里我把上界置为了全部派融合在一起,完全平均的分给每个人时每个人所得的体积,最后每个人所得必定小于等于这个数
        //printf("%f\n",temp);
        double rad = fun(0, temp+1, f); //下界置为0,因为每个人不可能分不到,上界加一为了使得temp包括在最后结果中。不一定非忒加一,加100也可以
        //printf("%f\n",rad);
        double result = rad * PI;
        printf("%.4f\n",result);  //这种输出自动四舍五入
        pie.clear();  //因为使用了全局的vector,所以最后还是要清空一下。
    }
    //fclose(stdin);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/aldo101/article/details/80583091