54 博弈转换

Cutting Game

POJ - 2311

Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his extraordinary wit. Recently Urej takes a great interest in a new game, and Erif Nezorf becomes the victim. To get away from suffering playing such a dull game, Erif Nezorf requests your help. The game uses a rectangular paper that consists of W*H grids. Two players cut the paper into two pieces of rectangular sections in turn. In each turn the player can cut either horizontally or vertically, keeping every grids unbroken. After N turns the paper will be broken into N+1 pieces, and in the later turn the players can choose any piece to cut. If one player cuts out a piece of paper with a single grid, he wins the game. If these two people are both quite clear, you should write a problem to tell whether the one who cut first can win or not.

Input

The input contains multiple test cases. Each test case contains only two integers W and H (2 <= W, H <= 200) in one line, which are the width and height of the original paper.

Output

For each test case, only one line should be printed. If the one who cut first can win the game, print "WIN", otherwise, print "LOSE".

Sample Input

2 2
3 2
4 2

Sample Output

LOSE
LOSE
WIN

一般情况而言,博弈都是最后走完的人赢得了比赛,但是,有些时候是相反的就是先完成了某一件事情后就先胜利了,问一下在某一种情形下,这个先手是否是有必胜的策略,这个会后我们可以这样想因为谁也不想给对手带来那种只有一行或是一列的状态,如果是有一行或是一列的话那么,现在面对的这个人就有必胜的策略,所以我们可以谁把最后的一步走了的话,就可以看作是谁赢了,这里的最后一步是下一步就必须是产生一行或是一列的情况,那么我们就可以把(2,2)(2,3)(3,2)看作是sg为0的状态就可以,所有的石子都在这三个点,

     aaa    
         
aaa        
         
         

对于这个表格的话,如果我们按照列给切开的话,我们肯定会选择的是第三列格子的两条边,因为只有这样的话,我们才不会给对方产生一列,同理行也是一样,我们可定会选第三行的两条边,这样我们就不会给对方产生一行,这样的话,我们就知道了,不论是按行,还是按列的来切割我们都会在距离边界是大于等于2的分界线上给切割;

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int Max = 500;

int sg[Max][Max];
int getsg(int n,int m){
    if(n<=0||m<=0)  return 0;
    if(sg[n][m]!=-1) return sg[n][m];
    bool visited[Max];
    memset(visited,0,sizeof(visited));
    for(int i=2;n-i>=2;i++){
        visited[(getsg(i,m)^getsg(n-i,m))]=1;
    }
    for(int i=2;m-i>=2;i++){
        visited[(getsg(n,i)^getsg(n,m-i))]=1;
    }
    for(int i=0;;i++){
        if(!visited[i]){
            return sg[n][m]=i;
        }
    }
}
int main(){
    int n,m;
    memset(sg,-1,sizeof(sg));
    for(int i=1;i<=200;i++){
        sg[1][i]=1;
        sg[i][1]=1;
    }
    while(scanf("%d %d",&n,&m)!=EOF){
        int key=getsg(n,m);
        if(key) printf("WIN\n");
        else printf("LOSE\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39792342/article/details/83420416
54
今日推荐