hdu3533 Light Switching Game

67 篇文章 1 订阅
Light Switching Game
Time Limit: 1000MS Memory Limit: 131072K
Total Submissions: 492 Accepted: 286

Description

The Light Switching Game is played on a 1000 × 1000 × 1000 cube of cells with a light in each cell, as Figure.1 shows. Initially, most of the lights are off while exactly N lights are on. Two players take moves alternately. A move consists of switching the lights at the corners of a cuboid, i.e. (x1,y1,z1), (x1,y1,z2), (x1,y2,z1), (x1,y2,z2), (x2,y1,z1), (x2,y1,z2), (x2,y2,z1), (x2,y2,z2) where 1 ≤ x1 x2 ≤ 1000, 1 ≤y1 y2 ≤ 1000, 1 ≤z1 z2 ≤ 1000 and the light at the corner (x2,y2,z2) must be on (and turned off after the move). Notice the cuboid is possibly degenerated to a rectangle, a line or even a single cell so that the player may also switching four, two or one besides eight lights in a move. The player loses the game when he can not take a move.


Figure.1

You will find out whether the second player can win if both players play optimally.

Input

There are multiple test cases.
Every test case starts with one line containing a single number N indicating the number of lights which is initially on. ( N ≤ 100)
Each of the next N lines contains the coordinates ( x, y, z) (1 ≤ x, y, z ≤ 1000) showing that the light at this position is on initially.

Output

One line for each test case which contains "Yes" or "No" indicating whether the second player can win the game.

Sample Input

4
5 11 30
5 19 19
23 15 6
2 26 16
3
9 20 9
8 1 28
30 22 26

Sample Output

Yes
No
论文题三维的nim积,转化成二维的就可以了!
#include <iostream>
#include <stdio.h>
using namespace std;
int pri[2][2]={0,0,0,1};
int get(int x,int y){
    if(x<2)return pri[x][y];
   int i=0,p,t,s;
    while(1){
        if((1<<(1<<i))<=x&&x<(1<<(1<<(i+1))))
        break;
        i++;
    }
    int m=1<<(1<<i);
    p=x/m;t=y/m;s=y-t*m;
    int t1=get(p,t);
    int t2=get(p,s);
    return m*(t1^t2)^get(m/2,t1);
}
int getsg(int x,int y){
    if(x<y)return getsg(y,x);
    if(x<2)return pri[x][y];
    int i=0,p,q,t,s;
    while(1){
        if((1<<(1<<i))<=x&&x<(1<<(1<<(i+1))))
        break;
        i++;
    }
    int m=1<<(1<<i);
    p=x/m;q=x-m*p;t=y/m;s=y-t*m;
    int t1=getsg(p,t);
    int t2=getsg(p,s)^getsg(q,t);
    int t3=getsg(q,s);
    return m*(t1^t2)^t3^get(m/2,t1);
}
int main()
{
    int n,ans,x,y,z;
    while(scanf("%d",&n)!=EOF){
        ans=0;
        while(n--){
            scanf("%d%d%d",&x,&y,&z);
            ans^=getsg(x,getsg(y,z));
        }
        if(!ans)printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值