二分答案,就是二分枚举答案,由于进行二分,所以复杂度log(n),比直接
for的时间更短。
记得上学那会, Fbs同学经常会欺负萝卜同学。有一次,他出了这么一道题目,想为难一下萝卜同学。题目是这样的: 有N个整数X_i, X_i值的范围从0到1000000000。要从中选出C个数( 2<=C<=N),使得任意两个数差的绝对值的最小值尽可能大,求这个最大值。 由于数据太大, 这次萝卜同学的确被难住了,怎么办呢,请你来帮帮萝卜同学吧!
【输入格式】
第一行是N和C。
接下来的N行,每行一个整数。
【输入格式】
一个整数,表示两两最小差距的最大值。
【输入输出样例】
aggr.in aggr.out
5 3
1
2
8
4
9
3
【样例解释】
选择1、 4和8或者选择1、 4和9。
【数据说明】
对于 30%的数据: 2<=N<=100;
对于 60%的数据: 2<=N<=1000;
对于 100%的数据: 2<=N<=100000, 2<=C<=N, 0<=X_i<=1000000000。
这题只要二分枚举绝对值差的最大值,直接暴力枚举这个值,即可求出
#include
using namespace std;
int i,j,k,n,m,tot,ans,l,r,mid,f[100005],use,c,s1;
int read(){
char c;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
int x=0,y=1;if(c=='-') y=-1;else x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';
return x*y;
}
int main()
{
n=read();c=read();
for(int i=1;i<=n;i++) f[i]=read();
sort(f+1,f+1+n);
l=1,r=1000000000;
while(l1){
mid=(l+r)>>1;s1=1;use=1;
for(int i=2;i<=n;i++){
if(f[i]-f[s1]>=mid){
use++;
s1=i;
}
}
if(use>=c) l=mid;
else r=mid;
}
printf("%d",l);
return 0;
}
题目描述
有N条绳子,它们的长度分别为Li。如果从它们中切割出K条长度相同的
绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位。
输入输出格式
输入格式:
第一行两个整数N和K,接下来N行,描述了每条绳子的长度Li。
输出格式:
切割后每条绳子的最大长度。
输入输出样例
输入样例#1:
4 11
8.02
7.43
4.57
5.39
输出样例#1:
2.00
这题是二分答案,只不过答案是小数,所以二分的时候要注意精度,注意浮点数误差。
只要枚举小数,算出ans,就可以完成答案。
#include
using namespace std;
int i,j,k,ans,use,n;
double f[100006],l,r,mid;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>f[i];
}
l=(double)1.00,r=(double)100000.00;
while(l0.0000001){
mid=(l+r)/2;ans=0;
for(int i=1;i<=n;i++)
ans+=f[i]/mid;
if(ans>=k) l=(double)mid;
else r=(double)mid;
}
printf("%.2f",l);
return 0;
}