poj 2456 二分法 最大化最小值


题目:http://poj.org/problem?id=2456

重新练习下二分法,发现还是手速不够

从这道题学到一下几点:

1、线性分几段的方法,看我的Judge()代码;

2、二分的while()最终打印的是down,而不是mid(我代码里写的是ans),或者up,

这么想:跳出循环的时候,假设while里的判断,Judge(ans)==1,那么down是正确解,up不是

Judge(ans)==0,那么ans跟up都不是正确解

综上,打印down才能输出正确解

3、调了好一会二才发现的bug:Judge函数里,if(cnt<c-1)return 0;  注意,cnt==1已经可以有两个牛仓了!!!


贴代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 100000+10;

int n,c;
int dis[MAXN];

int Judge(int s)
{
    int cnt=0,last=0,now=0;
    while(now<n)
    {
        
        //printf("last=%d now=%d cnt=%d s=%d\n",last,now,cnt,s);
        
        now=last+1;
        while(now<n && dis[now]-dis[last]<s)now++;
        if(now<n)
        {
            cnt++;
            last = now;
        }
    }
    if(cnt<c-1)return 0;/* 此处二逼过*/
    else    return 1;
}

int main()
{
    while(scanf("%d%d",&n,&c)!=EOF)
    {

        for(int i=0;i<n;i++)
            scanf("%d",&dis[i]);
        sort(dis,dis+n);
        int maxdis=dis[n-1]-dis[0];
        int up=maxdis+1,down=0,ans=up;//
        //printf("************%d\n",up);
        while(up-down>1)
        {
            ans=(up+down)/2;
            if(Judge(ans))down=ans;
            else up=ans;
        }
        printf("%d\n",down);//??ans?
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值