翻转游戏

原题链接

解法一:枚举+搜索

#include<bits/stdc++.h>
using namespace std;
int len;
string S;
bool search(bool state[])
{
    for(int i=0;i<len-1;i++){
        if(state[i]&&state[i+1]){
            state[i]=false;
            state[i+1]=false;
            if(!search(state)){
                state[i]=true;
                state[i+1]=true;
                return true;
            }
            else{//此步骤相当于悔棋 
                state[i]=true;
                state[i+1]=true;
            }
        }
    }
    return false;
}
bool canWin(string s)
{
    bool *state=new bool[s.length()]; 
    for(int i=0;i<s.length();i++){
        if(s[i]=='+')
            state[i]=true;
        else
            state[i]=false;
    }
    return search(state);
}

int main()
{
    cin>>S;
    len=S.length();
    if(canWin(S))
        printf("You win");
    else
        printf("You lose");
}
//输入1.-++++-  2.-+++++- 

解法二:Nim博弈

Nim游戏是博弈论中最经典的模型(之一),它又有着十分简单的规则和无比优美的结论 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatorial Games”。

满足以下条件的游戏是ICG(可能不太严谨):1、有两名选手;2、两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动;3、对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作、以前的任何操作、骰子的点数或者其它什么因素; 4、如果轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时无法进行移动),则这名选手负。根据这个定义,很多日常的游戏并非ICG。例如象棋就不满足条件3,因为红方只能移动红子,黑方只能移动黑子,合法的移动集合取决于轮到哪名选手操作。例如象棋就不满足条件3,因为红方只能移动红子,黑方只能移动黑子,合法的移动集合取决于轮到哪名选手操作。

string字符串的使用方法

转载两篇博弈好文:博弈好文1 与 博弈好文2

#include<bits/stdc++.h>
using namespace std;
bool canWin(string s)
{
    int *nim=new int[s.length()+1];
    bool *happen=new bool[s.length()+1];
    for(int i=0;i<=s.length();i++){
        for(int j=0;j<i-j-1;j++)
            happen[nim[j]^nim[i-j-2]]=true;
        bool nimEmpty=true;
        for(int j=0;j<=s.length();j++){
            if(!happen[j]&&nimEmpty){
                nimEmpty=false;
                nim[i]=j;
            }
            else
                happen[j]=false;
        }
    }
    int ans=0;
    int len=0;
    s+="-";//考虑到最后一个字符为'+'的情况 
    for(int i=0;i<s.length();i++){
        if(s[i]=='+')
            len++;
        else{
            ans^=nim[len];
            len=0;
        }
    }
    if(ans==0)
         return false;
    return true;
}
int main()
{
    string S;
    cin>>S;
    if(canWin(S))
        printf("You win");
    else
        printf("You lose");
}
//输入1.-++++-  2.-+++++- 

 

posted @ 2017-02-05 17:11  despair_ghost  阅读(457)  评论(0编辑  收藏  举报