首页 技术 正文
技术 2022年11月23日
0 收藏 988 点赞 5,063 浏览 2043 个字

题目链接

前言

发现自己三岁时的题目都不会做。

我发现我真的是菜得真实。

正文

神仙构造,分讨题。

不敢说有构造,但是分讨我只服这道题。

看上去像是一个类似 \(Nim\) 游戏的变种,经过不断猜测结论无果后果断弃疗。

(然后我就出门右转直接进了题解区),在这里记录一下自己的理解。

设 \(l_{i,j}\) 表示在 \(i\sim j\) 这个区间左边再加一堆 \(l_{i,j}\) 的石子时,先手必败。

同理,设 \(r_{i,j}\) 表示在 \(i\sim j\) 这个区间右边再加一堆 \(r_{i,j}\) 的石子时,先手必败。

(以下的所有证明以及验证我们都以 \(l_{i,j}\) 为准,\(r_{i,j}\) 情况相同)。

等等,如果上述满足条件的石子个数不唯一,怎么办?

好像不太好搞欸,是不是要再开一维数组?

既然不唯一的情况这么困难,为什么不想想会不会存在这种情况呢?

证明:

我们假设 \(l_{i,j}\) 存在两种可能 \(a\) 和 \(b\) ,且我们钦定 \(a < b\)。

既然 \(a\) 和 \(b\) 都满足要求,所以此时都是必败态。

但是很显然,我们可以让先手对于 \(b\) 的情况一直取直到 \(a\) 。

此时先手让后手到了一个必败态所以先手必败。??(对,这就是不唯一时的推理)

所以可以得出,\(l_{i,j}\) 一定是唯一的。

那万一 \(l_{i,j}\) 不存在怎么办?

等一等,\(l_{i,j}\) 是不是一定存在呢?

在这里我口胡一下:

因为对于所有的 \([i,j]\) 区间都不存在 \(l_{i,j}\) ,则对于所有从左边拿的一定是必胜态。

但是如果只有一堆石子 \(a\) 的话:此时可以发现 \(l_{i,j} = a\) 因为此时先手怎么取后手也学者他。

这样的话后手会取完最后一个石子。

所以,\(l_{i,j}\) 一定是存在的的。


现在来进行刺激的分讨过程。

我在这里会对每一种可能的结果进行简要的说明。

  • 首先我们先来考虑边界的情况:

    就和我之前说的一样 \(l_{i,i} = a_i\) , \(r_{i,i}\) 同理。

为了方便起见,我们令 \(x=a_j\) , \(L =l_{i,j-1}\) , \(R=r_{i,j-1}\) 。

  • ( \(x < L\) 且 \(x <R\) ) 或者 ( \(x > L\) 且 \(x >R\) )

    \(l_{i,j} = x\) 。

此时我们可以运用类似之前的方法,先手取什么,后手就取什么。

那么最后的结果就是先手先取完了左右两端石子中的一堆。

然后后手可以随便取另一边的一堆,使得此堆的数量变成 \(l_{i,j}\) 或 \(r_{i,j}\) 。

  • \(R<x<L\)

    \(L_{i,j} = x-1\)

假设先手先拿了左边这一堆。

那么假设还剩下了 \(x\) 个石子,如果 \(x<R\),后手把右侧的那一堆也给拿成 \(x\) 就成了( \(x < L\) 且 \(x <R\) )这种情况。

如果 \(x\geq R\),那么后手把最后那一堆拿成 \(x+1\),于是又回到了我们讨论的这种情况。

同理,我们也可以推出右边先取玩的的情况。

  • \(L<x<R\)

    \(L_{i,j} = x+1\)

    和上一种基本上是一摸一样,在这里就不讲了。

Code

#include <bits/stdc++.h>#define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)#define Enter puchar('\n')
#define quad putchar(' ')const int N = 1005;int T, a[N], l[N][N], r[N][N];signed main(void) {
// file("P2599");
std::cin >> T;
for (int test = 1, n; test <= T; test++) {
std::cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
l[i][i] = r[i][i] = a[i];
for (int len = 1; len <= n; len ++) {
for (int i = 1; i + len - 1 <= n; i++) {
int j = i + len - 1;
int L, R, x;
x = a[j];
L = l[i][j - 1]; R = r[i][j - 1];
if (R == x) l[i][j] = 0;
else if (x < L && x < R) l[i][j] = x;
else if (x > L && x > R) l[i][j] = x;
else if (R < x && x < L) l[i][j] = x - 1;
else l[i][j] = x + 1;
x = a[i];
L = l[i + 1][j]; R = r[i + 1][j];
if (L == x) r[i][j] = 0;
else if (x < L && x < R) r[i][j] = x;
else if (x > L && x > R) r[i][j] = x;
else if (R < x && x < L) r[i][j] = x + 1;
else r[i][j] = x - 1;
}
}
if (l[2][n] == a[1]) std::cout << "0" << std::endl;
else std::cout << "1" << std::endl;
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,965
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,486
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,331
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,114
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,747
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,781