昨天搜水题做,一不小心进一牛人的博客,
看到几道二分题的报告,忍不住做了一下,顺便把人家对题目的描述偷懒过来,说我邪恶吧( ⊙ 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;
}
#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;
}
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;
}
#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;
}