ポンゴネット英雄会第1回オンラインプログラミング大会:単語ゲーム


タイトルは以下の通り
甲乙二人は英語の単語でゲームをします.二人は交代で行い、一人一人が任意のアルファベットを削除するたびに、残りのアルファベットのシーケンスが厳格に単調に増加すれば(辞書順a入力:一連の英語の小文字、長さは15を超えず、最初の状態が厳格な単増のシーケンスではないことを保証します.
出力:1は甲が勝つことができることを表して、0は甲が勝つことができないことを表します.
例えばbadを入力すると、甲はbまたはaを削除することができ、残りはadまたはbdで、彼は勝って、1を出力します.
また、aaaを入力すると、甲は1つのaを削除するしかなく、乙は1つのaを削除し、残りの1つのaを削除し、乙は勝って、0を出力します.
分析:二人が十分に頭がいいと仮定したため、ある人がアルファベットを削除する番になったとき、彼は必ず自分にとって最も有利な選択を選ぶ.例えば、甲が削除する番になったとき、甲がゲームに勝つには、甲がそのアルファベットを削除した後、乙がどのように選択しても甲が勝つようにする選択があるに違いない.そうしないと、甲は負ける.
この問題はdfs+レコードテーブルの方法を採用することができます.2つのレコードテーブル(map)を用いて、甲乙2人が操作した単語のサブストリングをそれぞれ記録して、重複サブ問題の計算を防止する(例えば、単語abcdの場合、以下の2つの場合、単語のサブストリング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