POJ 3122 & 3258 & 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; }