2021-9-18
来源:Problem - 1382B - Codeforces
谷歌搜索「“First Second Second First First Second First” site://codeforces.com」就搜到了。
思路: 这道题其实并不是很难,但是一开始看到的时候有些畏难情绪,没有拿起纸笔分析。后来大概看了别人的思路,然后自己理了一遍,算是彻底弄懂了。
博弈论
结论:
- 当 a 序列都为 1 时,若 n 为奇数,先手必赢,否则后手必赢
- 当 a 序列不都为 1 时,偶数个前缀 1 先手必赢,奇数个前缀 1 后手必赢
推导:
1 是最特殊的元素。 如果当前堆只有 1 个石子,那么当前玩家别无选择,另一玩家从新的一堆开始。如果下一堆石子个数在 1 个以上,那么另一玩家可以选择拿走 a i − 1 a_i-1 ai−1 个,剩余 1 个继续让当前玩家处于劣势。
如果没有 1,那么先手是必赢的。因为先手可以在 1 , 2 , . . . , n − 1 1,2,...,n-1 1,2,...,n−1 堆中都取 a i − 1 a_i-1 ai−1 个,直到最后一堆自己取完就可以赢了。
前缀 1(处于序列前面的 1):如果只有前缀 1,且为偶数堆,则经过偶数轮操作,当 1 被取完后,此时玩家 1 仍处于先手,剩余部分没有 1,回到了第一种情况,先手赢;如果前缀 1 为奇数堆,取完前缀 1 后玩家 2 处于先手,即后手赢。
后缀 1 (处于序列后面的 1)。 实际上后缀 1 的个数并不影响结果,看一组例子
- [ 3 , 1 , 1 ] ,先手把第一堆 3 个全部取走,结果先手赢;
- [ 3 , 1 , 1 , 1 ] ,先手在第一堆取走 2 个,结果还是先手赢。
由此可知,后缀 1 不会影响结果,故可以忽略后缀的 1。
中缀 1 (处于序列中间的 1)。实际上中间的 1 同样不会影响结果。由第 3 种情况可以知道,第一个拿到非 1 石堆的人可以控制自己后面拿到哪一堆,同样,他可以控制自己是否拿到中间最后一堆是 1 的石子,也就可以决定自己的输赢。
如果不能理解自己可以举几组石子试试,注意拿石子之后尽量归到上面几种子问题的情况。综合上述推理,不难得到上面的结论。
代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TestS3E6 {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(in.readLine());
while (t-- > 0) {
int n = Integer.parseInt(in.readLine());
String[] strings = in.readLine().split(" ");
int count = 0;
for (String s : strings) {
if ("1".equals(s)) {
count++;
} else {
break;
}
}
if (count == n) {
// 由于是否都为1的情况和前缀1的情况相反,故这里给count++,统一输出格式
count++;
}
System.out.println((count & 1) == 1 ? "Second" : "First");
}
}
}
参考:
CodeForces-1382B-题解-思维、博弈_CapriceH的博客-CSDN博客
Codeforces 1382B - Sequential Nim(思维) - Hayasaka - 博客园 (cnblogs.com)
Sequential Nim(CodeForces - 1382B)【博弈】 - DIY-Z - 博客园 (cnblogs.com)