42 棋盘博弈&&尼姆博弈

B - Marbles

Using marbles as a currency didn't go so well in Cubicônia. In an attempt to make it up to his friends after stealing their marbles, the Emperor decided to invite them to a game night in his palace.

Of course, the game uses marbles, since the Emperor needs to find some use for so many of them. N

marbles are scattered in a board whose lines are numbered from 0 through L and the columns numbered from 0 through C. Players alternate turns. In his turn, a player must choose one of the marbles and move it. The first player to move a marble to position (0,0) is the winner. The movements are limited so the game could be more interesting; otherwise, the first player could just move a marble to position (0,0) and win. A movement consists in choosing an integer u greater than 0 and a ball, whose location is denoted by (l,c)

, and move it to one of the following positions, as long as it is inside the board:

  • (l−u,c)
  • or;
  • (l,c−u)
  • or;
  • (l−u,c−u)
  • .

Note that more than one marble can occupy the same position on the board.

As the Emperor doesn't like to lose, you should help him determine which games he should attend. Also, as expected, the Emperor always take the first turn when playing. Assuming both players act optimally, you are given the initial distribution of the marbles, and should find if it is possible for the Emperor to win if he chooses to play.

Input

The first line contains an integer N

(1≤N≤1000). Each of the following N rows contains two integers li and ci indicating on which row and column the i-th marble is in (1≤li,ci≤100

).

Output

Your program should print a single line containing the character Y if it is possible for the Emperor to win the game or N otherwise.

Examples

Input

2
1 3
2 3

Output

Y

Input

1
1 2

Output

N

这是一道棋盘博弈,题目的意思是在棋盘上有n个球,棋盘的大小是101*101的,每个人在进行一次操作的时候,这个人可以任选一个球然后是有三中可以任选其一的操作,假设当前的球在(x,y)处,这个可以将球推到,(x-u,y)处,(x,y-u)处,(x-u,y-u)处但是这里还有一个要求是这个推到的点必须是在棋盘的内部,问先手是否有策略首先将一个球推到(0,0)位置,

在一开始的时候,感觉简单的棋盘博弈,求sg打表异或结果非零赢,否则输,神奇过无用样例,但是提交wa3,,,,感觉没错啊想了一会想到,这样求算的是先手能否把最后一个球给送到(0,0)这个位置,,,,人家问的是是否是能首先把一个球给推到(0,0)位置,这样求算就不对了,,,,深思好久发现如果是没有在对角线上的点,无法一眼看出先手是否能赢,如果是都不在对角线上的话,

 0        1          2           3               4        

1                    *

2       *

3

4

这就是尼姆博弈了

这两个人肯定是最后都将球推到了两个星号的位置,正好是都采用最优的策略,谁(A)能把最后一个球推到了这两个位置(*),另外一个人(B)不论怎么推一个都会到边界或是对角线上,那么A就一定赢了,所以就是把(1,2),(2,1)位置的sg值赋值成为0,然后求其他点的sg值然后,异或完后看是否是非零,如果是非零,先手必有赢策略,否则没有

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Max = 1e3+10;
int sg[Max][Max];
bool visited[Max];
void pri(){
    for(int i=1;i<=102;i++){
       for(int j=1;j<=102;j++){
           sg[1][2]=0;
           sg[2][1]=0;
           memset(visited,0,sizeof(visited));
             for(int k=1;k<=max(i,j);k++){
              if(j>=k&&j-k!=i&&j-k>=1){
                visited[sg[i][j-k]]=1;
              }
              if(i>=k&&i-k!=j&&i-k>=1){
               visited[sg[i-k][j]]=1;
              }
              if(i>=k&&j>=k&&i-k!=j-k&&i-k>=1&&j-k>=1){
                visited[sg[i-k][j-k]]=1;
              }
           }
           for(int k=0;;k++){
         if(visited[k]==0){
            sg[i][j]=k;
            break;
         }
       }
       }
     }
}
int main(){
  int n;
  pri();
  int key=0;
  int key1=0;
   scanf("%d",&n);
   for(int i=1;i<=n;i++){
      int n1,n2;
      scanf("%d %d",&n1,&n2);
      if(n1==n2){
        key1=1;
        continue;
      }
      key^=sg[n1][n2];
    }
    if(key1==1){
       printf("Y\n");
       return 0;
    }
   if(key) printf("Y\n");
   else printf("N\n");
   return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39792342/article/details/82996781