icpc 北京网络赛 1006 贪心算法

来源:互联网 发布:陕西工商网络交易监管 编辑:程序博客网 时间:2024/04/26 06:49

网络赛结束,看了大神的代码以后才写出来的,这是一道贪心算法,选局部最优方案:就是相邻两个点不能直接到达做特别讨论。易证:如果两个点不能直接到达,那么每次让青蛙走两步到达(l+1)的距离是最优选择,如果现在青蛙的位置是now ,那么到达now 的那一步走了step,然后对now 后面的那个点进行讨论:如果length=stone[now+1]-stone[now],now+length<=l说明前一步可以到达now+1;这个时候更新now 的位置,试青蛙每一次都能够尽量地跳得远。这样还要把第一次的几种情况讨论一下才能ac,至于复杂度,也只有o(2*10^5),只需要更新now的位置,所以只要遍历一边所有石头的位置就好了


详细看下面ac代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;
int n,m,l;
int stone[200010];
int cnt;

void solve()
{
    sort(stone,stone+n+1);
    int step = 0;
    int now=0;
    int length;

    while(now!=n+1)
    {
        length=stone[now+1]-stone[now];
        if((step+length)<=l)
        {
            if(now==0)
            {
                cnt++;
            }
            step+=length;
            now+=1;
        }
        else if(length<=l)
        {
            step=length;
            now+=1;
            cnt++;
        }
        else if(length>l)
        {
            int a=length/(l+1);
            int b=length%(l+1);
            if(now==0)
            {
                now++;
                if(b==0)
                {
                    cnt+=2*a;
                    step=l;
                }
                else
                {
                    step=b;
                    cnt+=2*a+1;
                }
            }
            else
            {
                if(step+b<=l)
                {
                    now++;
                    cnt+=2*a;
                    step=step+b;
                }
                else
                {
                    now++;
                    cnt+=2*a+1;
                    step=b;
                }
            }
        }
    }
    printf("%d\n",cnt);
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int k=1;k<=t;k++)
    {
        cnt=0;
        scanf("%d%d%d",&n,&m,&l);
        stone[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&stone[i]);
        }
        stone[n+1]=m;
        printf("Case #%d: ",k);
        solve();
    }
    return 0;
}


0 0
原创粉丝点击