1413: [ZJOI2009]取石子游戏
Description
在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排。游戏由两个人进行,两人轮流操作,每次操作者都可以从最左或最右的一堆中取出若干颗石子,可以将那一堆全部取掉,但不能不取,不能操作的人就输了。 Orez问:对于任意给出一个初始一个局面,是否存在先手必胜策略。
Input
文件的第一行为一个整数T,表示有 T组测试数据。对于每组测试数据,第一行为一个整数n,表示有n堆石子;第二行为n个整数ai,依次表示每堆石子的数目。
Output
对于每组测试数据仅输出一个整数0或1。其中1表示有先手必胜策略,0表示没有。
Sample Input
1
4
3 1 9 4
4
3 1 9 4
Sample Output
0
数据范围
对于30%的数据 n≤5 ai≤105
对于100%的数据 T≤10 n≤1000 每堆的石子数目≤109
数据范围
对于30%的数据 n≤5 ai≤105
对于100%的数据 T≤10 n≤1000 每堆的石子数目≤109
这是一题思维量比较大的题目。 // 有些还待思想。
1 #include <cstdio> 2 3 const int kMaxN = 1000; 4 int t, n, s[kMaxN], fl[kMaxN][kMaxN], fr[kMaxN][kMaxN]; 5 6 int main() { 7 scanf("%d", &t); 8 while (t --) { 9 scanf("%d", &n); 10 for (int i = 0; i < n; ++ i) scanf("%d", &s[i]); 11 for (int i = 0; i < n; ++ i) fl[i][i] = fr[i][i] = s[i]; 12 for (int k = 1; k < n; ++ k) 13 for (int i = 0; i < n - k; ++ i) { 14 int j = i + k, p, q, x; 15 16 p = fl[i][j - 1], q = fr[i][j - 1], x = s[j]; 17 if (x == q) fl[i][j] = 0; 18 else if ((x < p && x < q) || (x > p && x > q)) fl[i][j] = x; 19 else if (p < q) fl[i][j] = x + 1; 20 else fl[i][j] = x - 1; 21 22 p = fr[i + 1][j], q = fl[i + 1][j], x = s[i]; 23 if (x == q) fr[i][j] = 0; 24 else if ((x < p && x < q) || (x > p && x > q)) fr[i][j] = x; 25 else if (p < q) fr[i][j] = x + 1; 26 else fr[i][j] = x - 1; 27 } 28 if (n == 1) printf("1\n"); 29 else printf("%d\n", (fr[0][n - 2] != s[n - 1])); 30 } 31 return 0; 32 }