翻转游戏
Posted despair_ghost
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了翻转游戏相关的知识,希望对你有一定的参考价值。
解法一:枚举+搜索
#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,因为红方只能移动红子,黑方只能移动黑子,合法的移动集合取决于轮到哪名选手操作。
#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.-+++++-
以上是关于翻转游戏的主要内容,如果未能解决你的问题,请参考以下文章