zoukankan      html  css  js  c++  java
  • LG P7078 贪吃蛇

    Description

    草原上有 $n$ 条蛇,编号分别为 $1,2,ldots,n$。初始时每条蛇有一个体力值$a_i$,我们称编号为 $x$ 的蛇实力比编号为 $y$ 的蛇强当且仅当它们当前的体力值满足$a_x > a_y$,或者 $a_x=a_y$ 且 $x > y$

    接下来这些蛇将进行决斗,决斗将持续若干轮,每一轮实力最强的蛇拥有选择权,可以选择吃或者不吃掉实力最弱的蛇:

    1. 如果选择吃,那么实力最强的蛇的体力值将减去实力最弱的蛇的体力值,实力最弱的蛇被吃掉,退出接下来的决斗。之后开始下一轮决斗。
    2. 如果选择不吃,决斗立刻结束。

    每条蛇希望在自己不被吃的前提下在决斗中尽可能多吃别的蛇(显然,蛇不会选择吃自己)。

    现在假设每条蛇都足够聪明,请你求出决斗结束后会剩几条蛇。

    本题有多组数据,对于第一组数据,每条蛇体力会全部由输入给出,之后的每一组数据,会相对于上一组的数据,修改一部分蛇的体力作为新的输入。

    Solution

    结论:当前最强的蛇吃掉最弱的蛇之后如果没有变成最弱的蛇(情况一),那么它一定会选择吃

    说明:

    假设当前最强的蛇叫张三,并且它吃掉最弱蛇之后不是最弱的,那么它下一轮必不会被吃

    • 如果张三吃掉最弱的之后仍然是最强的,不吃就显然很亏,所以张三会选择吃
    • 如果张三吃掉最弱的之后不是最强的,此时的最强的蛇一定没有刚才强,最弱的也没有刚才弱,如果此时最强蛇选择吃,那么它的体力值一定比张三小,就算死也会死在张三前面,又因为它足够聪明,不会使自己死,所以张三也不会死
    • 如果张三吃掉最弱的之后不是最强的,此时的最强的蛇一定没有刚才强,最弱的也没有刚才弱,如果此时最强蛇选择不吃,游戏结束,张三显然不死

    如果吃了之后变成最弱的蛇(情况二),张三是否死将由此时的最强蛇李四决定,张三非常聪明,仔细一想,如果李四决定吃张三,那么张三这一次就不会吃蛇使得自己成为最弱蛇,反之,如果李四不想吃,那么张三就可以放心吃

    那么李四是否吃呢?又可以分成以上两种情况进行讨论,假如李四吃后不是最弱蛇,那么李四会选择吃,张三预判到李四的操作,所以选择不吃来避免死亡

    由此会发现进入第二种情况后,吃与不吃交替出现:张三预判李四,李四预判王五,王五预判赵六,……,赵六选择吃,王五选择不吃,李四选择吃,张三选择不吃

    所以此时张三吃或不吃由之后这个“吃不吃”序列的长度的奇偶性决定

    并且这个序列长度$geq 2$,所以序列中必定有一个不吃,所以当游戏进入情况二后,不会重新回到情况一,而是会再吃$0$或$1$次,然后结束

    那么做法就是模拟两个阶段

    用set可以很好的维护最强蛇和最弱蛇,这种做法的时间复杂度$O(Tnlog n)$

    正解是用两个双端队列维护蛇的序列,使其的体力值单调,一头强一头弱

    每次从两个队列尾取出最强,从某个队列中取出最弱,不断重复,因为新产生的蛇的体力值也具有单调性,所以不需要$log n$数据结构维护

    时间复杂度$O(Tn)$

    #include<iostream>
    #include<utility>
    #include<cstdio>
    #include<deque>
    using namespace std;
    int T,n,a[1000005],ans,cnt;
    deque<pair<int,int> >q1,q2;
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return f*w;
    }
    int main()
    {
        T=read();
        for(int i=1;i<=T;i++)
        {
            q1.clear(),q2.clear(),ans=cnt=0;
            if(i==1)
            {
                n=read();
                for(int j=1;j<=n;j++) a[j]=read();
            }
            else
            {
                int k=read(),x,y;
                for(int j=1;j<=k;j++) x=read(),y=read(),a[x]=y;
            }
            for(int i=1;i<=n;i++) q1.push_back(make_pair(a[i],i));
            while(true)
            {
                if(q1.size()+q2.size()==2)
                {
                    ans=1;break;
                }
                int minn=q1.front().first,maxx,id;
                q1.pop_front();
                if(q2.empty()||q1.size()&&q1.back()>q2.back()) maxx=q1.back().first,id=q1.back().second,q1.pop_back();
                else maxx=q2.back().first,id=q2.back().second,q2.pop_back();
                pair<int,int>temp=make_pair(maxx-minn,id);
                if(temp>q1.front()) q2.push_front(temp);
                else
                {
                    ans=q1.size()+q2.size()+2;
                    while(true)
                    {
                        ++cnt;
                        if(q1.size()+q2.size()==1)
                        {
                            if(!(cnt%2)) --ans;
                            break;
                        }
                        int x,ID;
                        if(q2.empty()||q1.size()&&q1.back()>q2.back()) x=q1.back().first,ID=q1.back().second,q1.pop_back();
                        else x=q2.back().first,ID=q2.back().second,q2.pop_back();
                        temp=make_pair(x-temp.first,ID);
                        if(temp<q1.front()&&(q2.empty()||temp<q2.front()));
                        else
                        {
                            if(!(cnt%2)) --ans;
                            break;
                        }
                    }
                    break;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    贪吃蛇
  • 相关阅读:
    分布式服务框架 Zookeeper — 管理分布式环境中的数据
    分布式消息队列(二)
    分布式消息队列(一)
    数据库事务的四大特性以及事务的隔离级别
    php--yii2.0的安装
    php--字符串函数分类总结
    一张表有三个字段:id(城市id) Cityname(城市名) Privence(所属省份)如果要统计每个省份有多少城市请用SQL实现。
    TP自带的缓存机制
    php——n维数组的遍历——递归
    php--分享插件
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13968148.html
Copyright © 2011-2022 走看看