• icpc 北京网络赛 1006 贪心算法


    网络赛结束,看了大神的代码以后才写出来的,这是一道贪心算法,选局部最优方案:就是相邻两个点不能直接到达做特别讨论。易证:如果两个点不能直接到达,那么每次让青蛙走两步到达(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 ",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;
    }


  • 相关阅读:
    mysql 字符串先按照长度排序再按照ASCII码排序
    JMeter 压力测试文档
    Linux C监听鼠标键盘操作
    ubuntu 笔记本触摸板失灵
    git commit之后,想撤销commit
    清空iptables防火墙
    在k8s中搭建sonarqube并集成到jenkins
    redis集群搭建
    四叶草防火墙内外网映射
    k8smaster节点更换ip
  • 原文地址:https://www.cnblogs.com/hqwhqwhq/p/4555894.html
Copyright © 2020-2023  润新知