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; }