我解决了this problem on spoj:
两名玩家A和B玩下面的游戏。
首先,选择大小为N * M的矩阵M,并填充非零数字。
玩家A开始游戏,玩家交替玩游戏。
反过来,玩家选择任何至少有一个非零数量的行。在该行中,选择最左边的非零数字。设这个数字为K.玩家从中减去1到K之间的任何数字。
当矩阵M中的所有数字都为0时,游戏结束。
- 醇>
最后一名玩家赢得比赛。
给定N,M和初始矩阵,确定谁赢了比赛。假设两个玩家都玩得最好。
输入
第一行包含测试用例数T. 每个测试用例由2个数字N和M组成。遵循N行,每行有M个整数。第i行的第j个数是M [i] [j]。连续测试用例之间有一个空行。
输出
输出T行,每种情况一个。输出" FIRST"如果玩家A获胜,则输出" SECOND"。
示例
示例输入:
3 2 2 1 1 1 1 1 3 2 1 1 2 2 3 2 3 2
示例输出:
SECOND FIRST SECOND
这是一个数字问题。我使用传统的grundy方法解决了它,但我想到的另一种方法是给我错误的答案。这是第二种方法:
这种方法有什么问题?
#include <bits/stdc++.h>
using namespace std;
//code for fast input of integers
#define gc getchar_unlocked
void scanInt(int &x)
{
register int c = gc();
x = 0;
for(;(c<48 || c>57);c = gc());
for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
}
//end of code for fast input
int main(){
int t,n,m,odds,temp;
bool wins,flag;
scanInt(t);
while(t--){
wins = false;
scanf("%d%d",&n,&m);
for(int i = 0; i < n; i++){
odds = 0; // stores length of sequence of 1's at the beginning of each row
flag = true; // set to false on encountering first number not equal to 1 in the ith row
for(int j = 0; j < m; j++){
scanInt(temp);
if(flag == true){
if(temp != 1) flag = false;
else odds++;
}
}
if((odds % 2) == 1) wins ^= false;
else wins ^= true; //wins is XOR of result of each row as a separate game
}
puts(wins == true ? "FIRST\n" : "SECOND\n"); //if XOR of result of all rows is zero then first player loses
}
return 0;
}