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
",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
",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
",l);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/atmacmer/p/5290245.html