zoukankan      html  css  js  c++  java
  • 派(二分答案)

    05:派

    总时间限制: 
    1000ms
     
    内存限制: 
    65536kB
    描述

    我的生日要到了!根据习俗,我需要将一些派分给大家。我有N个不同口味、不同大小的派。有F个朋友会来参加我的派对,每个人会拿到一块派(必须一个派的一块,不能由几个派的小块拼成;可以是一整个派)。

    我的朋友们都特别小气,如果有人拿到更大的一块,就会开始抱怨。因此所有人拿到的派是同样大小的(但不需要是同样形状的),虽然这样有些派会被浪费,但总比搞砸整个派对好。当然,我也要给自己留一块,而这一块也要和其他人的同样大小。

    请问我们每个人拿到的派最大是多少?每个派都是一个高为1,半径不等的圆柱体。

    输入
    第一行包含两个正整数N和F,1 ≤ N, F ≤ 10 000,表示派的数量和朋友的数量。
    第二行包含N个1到10000之间的整数,表示每个派的半径。
    输出
    输出每个人能得到的最大的派的体积,精确到小数点后三位。
    样例输入
    3 3
    4 3 3
    样例输出
    25.133
    【思路】刘汝佳蓝本上的题目
    一开始我是没想到用二分答案,虽然这些题都是二分答案类型的,(当你做一道题目时,你不能正在学什么就往什么方面考虑,你要想,用什么方法为什么用这个方法)但是没有标志性的
    最小值最大的问法。然后我看了看题解。。。。。。
    介绍一下蓝本的思路:每个人分最多分所有派里面积最大的,要么无限小(这是答案范围);卡答案的条件就是能不能分得到,显然是用二分答案的
    所以 二分答案的题目 比较直接的问法 最小值最大 一看就是二分答案了,但是比较隐形的问法 首先要看看有这么几个特点1 能确定答案范围 2有卡答案的条件
    orz
    【代码】
     1 #include<iostream>
     2 #include<cstdio> 
     3 #include<cstdlib>
     4 #include<iomanip>
     5 #include<cmath>
     6 using namespace std;
     7 const double pi=acos(-1.0);// acos(-1.0)就是求-1.0的反余弦,经计算,acos(-1.0) 的值就是圆周率 
     8 const int MAXX=100009;
     9 double a[MAXX];
    10 bool ok(double);
    11 int n,f;
    12 int main()
    13 {
    14     int T;
    15     double maxx=0;
    16     scanf("%d",&T);
    17     while(T--)
    18     {
    19         scanf("%d%d",&n,&f);
    20         for(int i=0;i<n;i++)
    21         {
    22             int r;
    23             scanf("%d",&r);
    24             a[i]=pi*r*r;//每个派的面积 
    25             maxx=max(maxx,a[i]);//max函数里的变量类型相同 ,都是double 
    26         }
    27         double l=0,r=maxx;
    28         while(r-l>1e-5)//精确 二分答案的套路过程 
    29         {
    30             double m=(l+r)/2;
    31             if(ok(m))l=m;//扩大范围,看看每个人能不能分到更多 
    32             else
    33             r=m;
    34         }
    35         printf("%.3lf",l);//printf格式化输出会自动四舍五入; 
    36     }
    37     return 0;
    38 }
    39 bool ok(double s)//每人是否能分面积s的派 
    40 {
    41     int sum=0;
    42     for(int i=0;i<n;i++)
    43     {
    44         sum+=floor(a[i]/s);//向下取整,分不到s的浪费; 
    45     }
    46     return sum>=f+1;//能否分到 
    47 }
  • 相关阅读:
    纪念又一次ak
    hdu5618
    bzoj3393
    bzoj3438
    [JSOI2007]建筑抢修
    [CQOI2014]数三角形
    [BZOJ2662][BeiJing wc2012]冻结
    [NOIP2015]运输计划
    [ZJOI2006]超级麻将
    [APIO2009]抢掠计划
  • 原文地址:https://www.cnblogs.com/zzyh/p/6638583.html
Copyright © 2011-2022 走看看