POJ 博弈论


poj1704 Georgia and Bob

题目链接:http://poj.org/problem?id=1704

题意:如图所示,两个人在玩一个游戏,排成直线的格子上有n个棋子,两人依次将棋子向左移动可以移动任意格子,但是不能超过前面的棋子,也不允许将两个棋子放在同一个格子里面,无法进行移动的一方失败,问对于某个状态先手是否能赢。

分析:若n为偶数,则将棋子两两分为一组,转化为Nim,棋子间的格子即为每个数,若右边的格子左移则可视为取走了石子,若左边的格子左移,第二个人只要将增加的格子减去就可回到原来状态;若n为奇数则增加一个零号棋子坐标为零即可

#include
#include
#include
using namespace std;
int main(){
int a[1005],n,x;
cin>>x;
    while(x--){
        int n,x=0;
        cin>>n;
        for(int i=0;i>a[i];
        if(n%2==1)
            a[n++]=0;
        sort(a,a+n);
        for(int i=0;i

poj2234 Matches Game博弈论

题目链接:http://poj.org/problem?id=2234

题意:有M堆石子,每堆石子的数量已知,有两个玩家,轮流从这些石子中选取某一堆从中拿走若干个,至少拿一个,也可以全拿走,问先手能否取胜

最基本的Nim博弈,直接异或运算

#include
#include
using namespace std;
int main(){
    int n,a[25];
    while(cin>>n){
        for(int i=1;i<=n;i++)
            cin>>a[i];
            int x=a[1];
        for(int i=2;i<=n;i++)
            x=x^a[i];
        if(x!=0)
            cout<<"Yes"<
						  
					  

相关