您的位置:首页 > 其它

hdu 4004 The Frog's Games (二分+贪心)

2014-11-22 09:40 363 查看
题意:

一条长为L(1<=L<=10e9)的河,河里面有n(0<=n<=500000)个石头,已知每个石头离起点岸边的距离,可以踩着石头过河,

但最多只能跳m次(1<=m<=n+1)。问最大的跳跃能力应该是多少。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxn 500010

using namespace std;

int dis[maxn],n,m,l;

bool check(int x)
{
    if(x*(n+1)<l) return false;
    int pre = 0,cnt = 0,id = -1;
    for(int i=0;i<=n;i++)
    {
        //if(dis[i]-pre>x) return false; //  判断1
        while(i<=n && dis[i]-pre<=x)
            i++;
        if(i!=id)
        {
            id = i;
            i--;
            pre = dis[i];
            cnt++;
        }
        else return false;  //加这句或判断1都可以,如果不return false终止掉,i++后又满足i!=id了
    }
    if(cnt<=m && pre == dis
)
        return true;
    else return false;
}

int solve()
{
    int le = 0,ri = l,mid,ans;
    while(le<=ri)
    {
        mid = (le+ri)>>1;
        if(check(mid))
        {
            ri = mid-1;
            ans = mid;
        }
        else le = mid+1;
    }
    return ans;
}

int main()
{
    while(scanf("%d%d%d",&l,&n,&m)!=EOF)
    {
        for(int i=0;i<n;i++)
            scanf("%d",&dis[i]);
        dis
 = l;
        sort(dis,dis+n+1);
        printf("%d\n",solve());
    }
    return 0;
}


贪心的策略是:先判断距离Pre最近的点在跳的最大距离为x的条件下能不能跳到,

如果能,则向后找到一个能跳到的距离pre最远的点,跳数+1,更新pre。

改后稍微好看且逻辑清晰的代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxn 500010

using namespace std;

int dis[maxn],n,m,l;

bool check(int x)
{
    if(x*(n+1)<l) return false;
    int pre = 0,cnt = 0;
    for(int i=0;i<=n;i++)
    {
        if(dis[i]-pre>x) return false; //  判断1
        while(i<=n && dis[i]-pre<=x)
            i++;
        i--;
        pre = dis[i];
        cnt++;
    }
    if(cnt<=m && pre == dis
)
        return true;
    else return false;
}

int solve()
{
    int le = 0,ri = l,mid,ans;
    while(le<=ri)
    {
        mid = (le+ri)>>1;
        if(check(mid))
        {
            ri = mid-1;
            ans = mid;
        }
        else le = mid+1;
    }
    return ans;
}

int main()
{
    while(scanf("%d%d%d",&l,&n,&m)!=EOF)
    {
        for(int i=0;i<n;i++)
            scanf("%d",&dis[i]);
        dis
 = l;
        sort(dis,dis+n+1);
        printf("%d\n",solve());
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: