庞果网英雄会第一届在线编程大赛:单词博弈

题目如下

甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序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

原文地址:https://www.cnblogs.com/TenosDoIt/p/3485090.html