题目描述:在NIM博弈的基础上加一个限制条件,若先手取石块的那堆石块没有被取完,那么后手必须在这堆石块上取石头。
思路:推了一个小时才做出来,怎么说呢,结论不难推场上很多很多16级同学都退出来了,但我作为15级学姐却花费了那么长的时间才做出这道题。其实题目并不难,但是可能因为之前很少做出博弈题,所以对它有一定的畏惧吧,自己心里先怕了又怎么可能很快的做出来呢。扯远了,还是说一下结论吧,新加的这个限制条件对先手来说有很大的优势,因为如果初始的石堆中原本有奇数个1比如3 2 8 1 1 1 先手总可以先拿不为1的石堆使其只剩下一个石头,那么后手必须拿这个石头,这样原本不为1的石堆就被拿完了,剩下1 1 1 先手必胜。如果原本石堆有偶数个1比如3 2 5 6 7 1 1 ,先手总可以将某一不为一的石堆看做一,比如拿光3 2 5 6后,先手不再让石堆7只剩一个石块,而是直接全部拿走,那么轮到后手拿时,只剩下1 1,先手必胜。如果原本石堆石块数量全为1,那么结果也是很明显的,若为奇数个,先手胜,若为偶数个,后手胜。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstdlib>
#include<sstream>
#include<deque>
#include<stack>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 1e3 + 10;
const int mod = 10000007;
const int dx[] = {1, -1, 0, 0, -1, -1, 1, 1};
const int dy[] = {0, 0, -1, 1, -1, 1, -1, 1};
const int Dis[] = {-1, 1, -5, 5};
const double inf = 0x3f3f3f3f;
int n, m;
int main(){
int t;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
int ans = 0;
bool ok = false;
for(int i = 0; i < n; ++i){
scanf("%d", &m);
if(m != 1) ok = true;
else ++ans;
}
if(!ok){
if(ans % 2 == 0) printf("piloop\n");
else printf("poopi\n");
}
else{
printf("poopi\n");
}
}
return 0;
}