题目链接:点这里。
Problem Description
Agrael likes play a simple game with his friend Animal during the classes. In this Game there are n piles of stones numbered from 1 to n, the 1st pile has M1 stones, the 2nd pile has M2 stones, ... and the n-th pile contain Mn stones. Agrael and Animal take turns to move and in each move each of the players can take at most L1 stones from the 1st pile or take at most L2 stones from the 2nd pile or ... or take Ln stones from the n-th pile. The player who takes the last stone wins.
After Agrael and Animal have played the game for months, the teacher finally got angry and decided to punish them. But when he knows the rule of the game, he is so interested in this game that he asks Agrael to play the game with him and if Agrael wins, he won't be punished, can Agrael win the game if the teacher and Agrael both take the best move in their turn?
The teacher always moves first(-_-), and in each turn a player must takes at least 1 stones and they can't take stones from more than one piles.
Input
The first line contains the number of test cases. Each test cases begin with the number n (n ≤ 10), represent there are n piles. Then there are n lines follows, the i-th line contains two numbers Mi and Li (20 ≥ Mi > 0, 20 ≥ Li > 0).
Output
Your program output one line per case, if Agrael can win the game print "Yes", else print "No".
Sample Input
2
1
5 4
2
1 1
2 2
Sample Output
Yes
No
【题意】
老师和学生进行多次博弈,每次博弈的时候有很多堆,每堆告诉了每次最多选多少。然后问你一局游戏中,学生是否能必胜(老师先手)。其实也就是问你是否能后手必胜。
【分析】
后手必胜的意思就是先手不能必胜。然后我们直接求是否能先手必胜就行了。其中对于每一堆来说其实就是一个单纯的nim游戏。然后对于所有堆直接求nim和然后判断是否为0就行了。而且这题数据量巨小,打个表直接0MS。
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<sstream>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS_1(a) memset(a,-1,sizeof(a))
#define MSinf(a) memset(a,0x3f,sizeof(a))
#define sin1(a) scanf("%d",&(a))
#define sin2(a,b) scanf("%d%d",&(a),&(b))
#define sll1(a) scanf("%lld",&(a))
#define sll2(a,b) scanf("%lld%lld",&(a),&(b))
#define sdo1(a) scanf("%lf",&(a))
#define sdo2(a,b) scanf("%lf%lf",&(a),&(b))
#define inf 0x3f3f3f3f
//#define lson i<<1,l,mid
//#define rson ((i<<1)|1),mid+1,r
#define uint unsigned int
typedef pair<int,int> PII;
#define A first
#define B second
#define pb push_back
#define MK make_pair
#define ll long long
template<typename T>
void read1(T &m) {
T x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
m = x*f;
}
template<typename T>
void read2(T &a,T &b) {
read1(a);
read1(b);
}
template<typename T>
void read3(T &a,T &b,T &c) {
read1(a);
read1(b);
read1(c);
}
template<typename T>
void out(T a) {
if(a>9) out(a/10);
putchar(a%10+'0');
}
template<typename T>
void outn(T a) {
if(a>9) out(a/10);
putchar(a%10+'0');
puts("");
}
using namespace std;
///------------------------------------------------------------------------------------
int SG[25][25];//i个棋子,每次最多j个
int getSG(int i,int j)
{
bool flag[25];
memset(flag,false,sizeof(flag));
rep1(k,1,j)
if(i>=k)
flag[SG[i-k][j]]=true;
rep0(i,0,25) if(!flag[i]) return i;
}
void inti(void)
{
rep0(i,1,25)
rep0(j,1,25)
SG[i][j] = getSG(i,j);
}
int main() {
inti();
int T;
read1(T);
while(T--)
{
int len,a,b,ans=0;
read1(len);
while(len--)
{
read2(a,b);
ans^=SG[a][b];
}
puts(ans?"No":"Yes");
}
return 0;
}