SP20951 题解
思路
题目标题(SNIM)已经在提示我们这道题的做法了,博弈论(Nim 游戏)。
由于要求取完之后单调不降,对原石子堆 $a$ 做一个前缀差,记录在数组 $b$ 中,代表实际游戏要用到的石子堆。
假设我们在第 $i$ 堆石子中取了 $x$ 个,则 $b_i=(a_i-x)-a_{i-1}=a_i-a_{i-1}-x$,比原来少了 $x$ 个石子,但是 $b_{i+1}=a_{i+1}-(a_{i}-x)=a_{i+1}-a_i+x$,也就是将这 $x$ 个转移到了第 $i+1$ 堆。
这就是一道反着的阶梯 Nim 的模板。
所以策略如下:
-
先手将奇数堆多的石子转移到偶数堆。
-
若对方移动奇数堆,先手继续移动奇数堆,否则将对方移过来的石子移动到偶数堆。
-
在多次移动之后,先手可以先对方一步把奇数堆的石子转移到偶数堆,直到将石子转移到第 $0$ 堆,对方不能移动。
所以对答案有影响的只有奇数堆,在奇数堆上跑 Nim 游戏策略即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
int t,n,ans;
int a[maxn],b[maxn];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
ans=0;
for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i]-a[i-1];
for(int i=n;i>=0;i-=2)ans^=b[i];
if(ans)puts("TAK");
else puts("NIE");
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现