[ZJOI2009]取石子游戏
题目描述
在研究过 Nim 游戏及各种变种之后,Orez 又发现了一种全新的取石子游戏,这个游戏是这样的:
有 nnn 堆石子,将这 nnn 堆石子摆成一排。游戏由两个人进行,两人轮流操作,每次操作者都可以从最左或最右的一堆中取出若干颗石子,可以将那一堆全部取掉,但不能不取,不能操作的人就输了。
Orez 问:对于任意给出一个初始一个局面,是否存在先手必胜策略。
输入格式
文件的第一行为一个整数 TTT,表示有 TTT 组测试数据。对于每组测试数据:
第一行为一个整数 nnn,表示有 nnn 堆石子。
第二行为 nnn 个整数 a1,a2,…,ana_1, a_2, \ldots , a_na1,a2,…,an,依次表示每堆石子的数目。
输出格式
对于每组测试数据仅输出一个整数 000 或 111。其中 111 表示有先手必胜策略,000 表示没有。
输入输出样例
样例输入1
1
4
3 1 9 4
样例输出1
0
说明/提示
对于 30%30 \%30% 的数据,n≤5n \le 5n≤5,ai≤105a_i \le {10}^5ai≤105。
对于 100%100 \%100% 的数据,1≤T≤101 \le T \le 101≤T≤10,1≤n≤10001 \le n \le 10001≤n≤1000,1≤ai≤1091 \le a_i \le {10}^91≤ai≤109。
Code
#include <bits/stdc++.h>
using namespace std;
int T;
int n, a[1005], l[1005][1005], r[1005][1005];
int main()
{
cin >> T;
while (T--)
{
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
}
for (int i = 1; i <= n; ++i)
{
l[i][i] = r[i][i] = a[i];
}
for (int len = 2; len <= n; ++len)
{
for (int i = 1, j = i + len - 1; j <= n; ++i, ++j)
{
int L = l[i][j - 1], R = r[i][j - 1], x = a[j];
if (x == R)
l[i][j] = 0;
if (x < L && x < R)
l[i][j] = x;
if (R < x && x < L)
l[i][j] = x - 1;
if (L < x && x < R)
l[i][j] = x + 1;
if (x > L && x > R)
l[i][j] = x;
L = l[i + 1][j], R = r[i + 1][j], x = a[i];
if (x == R)
r[i][j] = 0;
if (x < L && x < R)
r[i][j] = x;
if (R < x && x < L)
r[i][j] = x + 1;
if (L < x && x < R)
r[i][j] = x - 1;
if (x > L && x > R)
r[i][j] = x;
}
}
if (l[2][n] == a[1])
puts("0");
else
puts("1");
}
}
1465



被折叠的 条评论
为什么被折叠?



