YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

http://www.51nod.com/Challenge/TopicProblemList.html#topicId=291

二分答案思路就是先确定好答案的范围,一般越大越好,去个left为答案的最小取值,right为答案的最大取值

然后二分,,同时判断当前状态时候满足答案,如果满足的话,还要考虑是否为最优的选择。

如题目:

工厂里面,有n根待加工的铁棒,长度以米为单位,精确到小数点后两位(即厘米),现在市场上需求量是m根相同长度的铁棒。现在厂长想把这n根铁棒进行切割,切割的时候要精确到厘米,比如说,原来铁棒是1.00米的,那么可以切成0.50和0.50的,但是不能切成0.499和0.501的。并且不能将两根铁棒拼成一根铁棒。现在厂长想知道切出来的m根铁棒最长能有多长。

单组测试数据。
第一行给出两个整数n(1 <= n<= 10000)和m(1 <= m< = 10000)。
接下来n行给出原始铁棒的长度L[1],L[2],L[3],...,L[n] ,(1<=L[i]<=100,000)。以米为单位,精确到小数点后两位。

输出

输出一个小数表示答案,精确到小数点后两位。

AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1E5+7;
ll arr[N];
ll x,y;
ll pos=0;
ll sum(ll x1){
    ll ans=0;
    for(int i=0;i<pos;i++){
        ans+=arr[i]/x1;
    }
    return ans;
}
int main(){
    cin>>x>>y;
    float xx;
    ll base=100;
    for(int i=1;i<=x;i++){
        scanf("%f",&xx);
        arr[pos++]=xx*base;
    }
    sort(arr,arr+pos);
    ll left=0;
    ll right=arr[pos-1];
    ll ans=0;
    while(left<=right){
        ll mid=(left+right)/2;
        if(mid==0) break;
        ll y1=sum(mid);
        if(y1>=y){
            left=mid+1;
            ans=mid;
        }
        else right=mid-1;
    }
    float yy=ans/100.0;
    printf("%.2f\n",yy);
    return 0;
}

 



posted on 2019-09-13 21:03  Target--fly  阅读(365)  评论(0编辑  收藏  举报