POJ 3258 \poj 3273\poj 3122 【二分】

昨天搜水题做,一不小心进一牛人的博客,
看到几道二分题的报告,忍不住做了一下,顺便把人家对题目的描述偷懒过来,说我邪恶吧( ⊙ o ⊙ )!
POJ 3258 River Hopscotch
http://poj.org/problem?id=3258
长为L的河道,起点在0位置,终点为L位置,期间分布着n块石头,石头不会重叠
求拆掉其中的m块石头,使相邻两石头间的距离的最小值最大,并输出这个值。。。
额。。。貌似描述不清。。。将就一下,(*^__^*) 嘻嘻……
View Code
#include<stdio.h>
#include
<string.h>
#include
<algorithm>
usingnamespace std;
constint N =50000+10;
long rocks[N];
long l,n,m;

bool ok(long v)
{
int i;
int remove =0;
int pre =0;
for(i=1;i<n;i++)
{
if(rocks[i]-rocks[pre]<v)
{
remove
++;
if(remove>m)returnfalse;
}
else
{
pre
= i;
}
}

returntrue;
}
int main()
{


while(scanf("%ld%ld%ld",&l,&n,&m)!=EOF)
{
int i;
for(i=1;i<=n;i++)
scanf(
"%ld",&rocks[i]);
rocks[
0]=0;
rocks[n
+1]=l;
n
+=2;

sort(rocks,rocks
+n);

long left =0;
long right = l;
long ans = l;
while(left<=right)
{
long mid = (left+right)>>1;
if(ok(mid))
{
ans
= mid;
left
= mid+1;
}
else
right
= mid-1;
}

printf(
"%ld\n",ans);

}
return0;
}
poj 3273 Monthly Expense
题意:给你天数n,和每天需要花的钱,让你把这些天分成m份(每份都是连续的天),
要求每份的和尽量少,输出这个和。
分析:二分时,left取支出最多的那一天的花费,right取总花费即可 
http://poj.org/problem?id=3273
#include<stdio.h>
constint N =100000+10;
int day[N];
int n,m;

bool ok(__int64 v)
{
int tm = m;
int i =0;
while(tm>0&&i<n)
{
__int64 curs
= v - day[i];
if(curs<0)returnfalse;
i
++;
while(i<n&&curs>=day[i])
{
curs
-=day[i];
i
++;
}
tm
--;
}

if(i==n)returntrue;
returnfalse;
}
int main()
{

while(scanf("%d%d",&n,&m)!=EOF)
{
int i;
__int64 ans;
__int64 sum
=0;
__int64 left
=0;
for(i=0;i<n;i++)
{
scanf(
"%d",&day[i]);
if(day[i]>left)left=day[i];
sum
+=day[i];
}


__int64 right
= sum;
ans
=0;
while(left<=right)
{
__int64 mid
= (left+right)>>1;
if(ok(mid))
{
ans
= mid;
right
= mid-1;
}
else
left
= mid+1;
}

printf(
"%I64d\n",ans);

}
return0;
}
poj 3122 Pie

题意是:某人在生日的时候请朋友一起吃pie,但是他的朋友十分挑剔,
如果有人分到了一块比其他人大的pie,那么其他的朋友就会抱怨,因此每个人,
包括主人,都必须分到大小一样的pie,但是每个人的pie只能是从一块大的圆形pie中切出来的,
要求求出每人能分到的最大的pie,给定圆形pie的数量 n,朋友数量m,以及每个pie的半径r
#include<stdio.h>
#include
<algorithm>
usingnamespace std;
constint N =10000+10;
double s[N];
int r[N];
constdouble pi =3.141592653589793238462643383279502884197169399;
int n,f;

bool ok(double v)
{
int i = n-1;
double tf = f;
while(i>=0&&tf>0)
{
int cur = (int)(s[i]/v);
tf
-=cur;
i
--;
}
if(tf>0)returnfalse;
returntrue;
}
int main()
{
int T,i;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{

scanf(
"%d%d",&n,&f);
f
++;
for(i=0;i<n;i++)
scanf(
"%d",&r[i]);

sort(r,r
+n);
for(i=0;i<n;i++)
{
s[i]
= (double(r[i]*r[i]));
}

double left,right;
right
= s[n-1];
left
=0;
double ans =0;
while((right-left)>=0.0000001)//注意精度处理
{
double mid = (left+right)/2;
if(ok(mid))
{
ans
= mid;
left
= mid;
}
else
right
= mid;
}

printf(
"%.3lf\n",ans*pi);
}
}
return0;
}
原文地址:https://www.cnblogs.com/AndreMouche/p/1982906.html