zoukankan      html  css  js  c++  java
  • 庞果网英雄会第一届在线编程大赛:单词博弈

    题目如下

    甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < c <....<z),则这个人胜利。两个人都足够聪明(即如果有赢的方案,都不会选输的方案 ),甲先开始,问他能赢么?

    输入: 一连串英文小写字母,长度不超过15,保证最开始的状态不是一个严格单增的序列。

    输出:1表示甲可以赢,0表示甲不能赢。

    例如: 输入 bad, 则甲可以删掉b或者a,剩余的是ad或者bd,他就赢了,输出1。

    又如: 输入 aaa, 则甲只能删掉1个a,乙删掉一个a,剩余1个a,乙获胜,输出0。


    分析:由于假设了两人足够聪明,即轮到某个人删除字母的时候,他一定会选对自己最有利的选择。例如轮到甲删除的时,甲想赢得游戏,那么一定存在一种选择使得甲删除该字母后,无论乙怎么选择都会导致甲赢,否则甲就会输。

    这一题可以采用dfs+记录表的方法,利用两个记录表(map)分别记录甲乙两人已经操作过的单词子串以防止计算重复子问题(例如对于单词abcd,下面两种情况下对单词子串cd有重复计算,甲删除a,乙再删除b,然后甲要对单词cd进行删除;甲删除b,乙删除a,甲对单词cd进行删除)。

    记录表amap[s] = true 表示字符串s由甲来删除时,甲会赢得游戏,= false则表示甲会输

    记录表bmap[s] = true 表示字符串s由乙来删除时,甲会赢得游戏,= false则表示甲会输(注意是甲是否会赢得游戏)

    本文地址

    class Test {
    public:
        typedef map<string, bool> Map;
        static int who (string   word)
        {
            //用map保存子问题,防止重复计算
            //amap[s]表示字符串s由甲操作时甲能否获胜
            //bmap[s]表示字符串s由乙操作时甲能否获胜
            Map amap, bmap;
            return (int)dfs(word, 1, amap, bmap);
        }
    private:
        //判断字符串是否严格递增
        static bool isIncrease(string &s)
        {
            int len = s.size();
            for(int i = 1; i < len; i++)
                if(s[i] <= s[i-1])return false;
            return true;
        }
    
        //id == 1表示接下来由甲操作,否则是乙
    	//返回true表示甲会赢得游戏,返回false则甲会输
        static bool dfs(string &s, bool id, Map &amap, Map &bmap)
        {
            if(isIncrease(s))
            {
                if(id == 0)
                    return true;
                else return false;
            }
            int len = s.size();
            for(int i = 0; i < len; i++)
            {
                string subs = s;
                subs.erase(i,1);
                bool tmp;
                if(id == 0)
                {//由乙操作时,要所有情况返回true,即所有情况乙都会输,甲就赢得游戏
                    if(bmap.find(subs) == bmap.end())
                    {
                        tmp = dfs(subs, id^true, amap, bmap);
                        bmap[subs] = tmp;
                    }
                    else tmp = bmap[subs];
                    if(tmp == false)return false;
                }
                else
                {//由甲操作时,只要一种情况返回true,甲就赢得游戏
                    if(amap.find(subs) == amap.end())
                    {
                        tmp = dfs(subs, id^true, amap, bmap);
                        amap[subs] = tmp;
                    }
                    else tmp = amap[subs];
                    if(tmp == true)return true;
                }
            }
            if(id == 0)
                return true;
            else return false;
        }
    };

    调用Test::who(sting word) 来判断对于单词word甲是否会赢

    【版权声明】转载请注明出处http://www.cnblogs.com/TenosDoIt/p/3485090.html

  • 相关阅读:
    Javascript基础——函数
    Javascript基础知识(二)
    Javascript基础知识(一)
    base64编码成功后并在页面上显示出想要展现的图片张数
    JavaScript结合canvas获取图片某一区域的rgba平均值的方法
    继承的几种方法
    简易模拟下拉框
    无缝轮播图
    事件的绑定方式
    数组
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3485090.html
Copyright © 2011-2022 走看看