首页 > 其他 > 详细

POJ 3122 & 3258 & 3273 #二分

时间:2016-03-18 07:04:30      阅读:143      评论:0      收藏:0      [点我收藏+]

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

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;
}

POJ 3122 & 3258 & 3273 #二分

原文:http://www.cnblogs.com/atmacmer/p/5290245.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!