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

Sample Output

0

数据范围
对于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 }
View Code

 

 
posted @ 2019-06-24 14:44  zjxxcn  阅读(205)  评论(0编辑  收藏  举报