POJ 3122 & 3258 & 3273 #二分

以下三道都是经典二分,道理都差不多,代码就贴在一起了。

POJ 3122    POJ 3258    POJ 3273

POJ 3122:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define PI 3.14159265359 //ÓÃ3.1415926»áWA¡£¡£¡£
double pie[10005]; int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,f,r;
double maxp=0.0;
scanf("%d%d",&n,&f);
f++;
for(int i=0;i<n;i++)
{
scanf("%d",&r);
pie[i]=r*r*PI;
maxp=max(maxp,pie[i]);
}
double left=0.0,right=maxp;
while(left+1e-6<right)
{
double mid=(left+right)/2.0;
int sum=0;
for(int i=0;i<n;i++)
sum+=floor(pie[i]/mid);
if(sum>=f)
left=mid;
else right=mid;
}
printf("%.4lf\n",left);
}
return 0;
}

POJ 3258:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; int main()
{
int L,n,m,d[50005];
while(~scanf("%d%d%d",&L,&n,&m))
{
int l=L,r=L,mid;
d[0]=0; d[n+1]=L;
for(int i=1;i<=n;i++)
scanf("%d",&d[i]);
sort(d,d+n+2);
for(int i=1;i<=n+1;i++)
l=min(l,d[i]-d[i-1]); while(l<r)
{
mid=(l+r)>>1;
int cnt=0,sum=0;
for(int i=1;i<=n+1;i++)
{
if((sum+=(d[i]-d[i-1]))<=mid) //注意加括号
cnt++;
else sum=0;
}
if(cnt>m)
r=mid;
else l=mid+1;
}
printf("%d\n",l);
}
return 0;
}

POJ 3273:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; int main()
{
int n,m,pay[100005];
while(~scanf("%d%d",&n,&m))
{
int l=0,r=0;
for(int i=0;i<n;i++)
{
scanf("%d",&pay[i]);
l=max(l,pay[i]);
r+=pay[i];
}
while(l<r)
{
int cnt=0,sum=0;
int mid=(l+r)/2;
for(int i=0;i<n;i++)
{
sum+=pay[i];
if(sum>mid)
{
cnt++;
sum=pay[i];
}
}
if(cnt<m)
r=mid;
else l=mid+1;
}
printf("%d\n",l);
}
return 0;
}
上一篇:十一个行为模式之状态模式(State Pattern)


下一篇:读《编写可维护的JavaScript》第11章总结