LightOJ1315 Game of Hyper Knights(SG函数+博弈论)

LightOJ1315 Game of Hyper Knights(SG函数+博弈论)

Description
A Hyper Knight is like a chess knight except it has some special moves that a regular knight cannot do. Alice and Bob are playing this game (you may wonder why they always play these games!). As always, they both alternate turns, play optimally and Alice starts first. For this game, there are 6 valid moves for a hyper knight, and they are shown in the following figure (circle shows the knight).
在这里插入图片描述

They are playing the game in an infinite chessboard where the upper left cell is (0, 0), the cell right to (0, 0) is (0, 1). There are some hyper knights in the board initially and in each turn a player selects a knight and gives a valid knight move as given. And the player who cannot make a valid move loses. Multiple knights can go to the same cell, but exactly one knight should be moved in each turn.
Now you are given the initial knight positions in the board, you have to find the winner of the game.

Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 1000) where n denotes the number of hyper knights. Each of the next n lines contains two integers x y (0 ≤ x, y < 500) denoting the position of a knight.
Output
For each case, print the case number and the name of the winning player.
Sample Input
2
1
1 0
2
2 5
3 5
Sample Output
Case 1: Bob
Case 2: Alice

题意

有t组数据,每组数据有n个棋子放在棋盘上,有两个人A,B,两个人轮流移动棋子,A先,若轮到某个人,没有棋子可以移的话,就判定给人失败。移法有6种,如图所示。
套SG函数递归板子,非常简单。准确说是套板子很简单,但是SG函数啊啥的还是不理解,这异或来异或去的,有毛病啊。

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<functional> 
#include<map>
#include<unordered_map>
#define lowbit(x) ((x)&-(x));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+10,NN=1e3+10,INF=0x3f3f3f3f,LEN=110;
const ll MOD=1e9+7;
const ull seed=31;
int sg[NN][NN],dis[6][2]={{-2,1},{-3,-1},{-2,-1},{-1,-2},{-1,-3},{1,-2}};
int getSG(int x,int y){
	if(sg[x][y]!=-1) return sg[x][y];
	bool vis[NN]={false};
	for(int i=0;i<6;i++){
		int tempx=x+dis[i][0],tempy=y+dis[i][1];
		if(tempx<0) continue;
		if(tempy<0) continue;
		vis[getSG(tempx,tempy)]=true;
	}
	for(int i=0;;i++) if(!vis[i]) return sg[x][y]=i;
}
void init(){
}
int main(){
	int t,T=0;
	scanf("%d",&t);
	memset(sg,-1,sizeof sg);
	while(t--){
		int n,ans=0;
		scanf("%d",&n);
		for(int i=0;i<n;i++){
			int x,y;
			scanf("%d%d",&x,&y);
			ans^=getSG(x,y);
		}
		printf("Case %d: ",++T);
		if(ans) printf("Alice\n");
		else printf("Bob\n");
	}
}

猜你喜欢

转载自blog.csdn.net/Hc_Soap/article/details/107702068