1 条题解
-
0
自动搬运
来自洛谷,原作者为

yybyyb
**搬运于
2025-08-24 21:39:30,当前版本为作者最后更新于2018-10-08 19:42:57,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
神仙题.jpg。是真的神仙。
发现函数等东西完全找不到规律,无奈只能翻题解。首先设表示在这一段区间的左侧放上一堆数量为的石子后,先手必败。同理定义表示右侧。
首先我们可以证明唯一,假设存在两个,显然较大的那个可以通过一步转移转移到较小的那个,所以不合法。因此唯一。
接下来考虑如何证明一定存在。假设不存在,那么对于这段区间而言,在左边加上任意一堆石子先手都必胜,既然先手必胜意味着先手进行一步操作之后可以到达一个必败态,这里分情况讨论。假设先手拿的是最左边的一堆石子,因为不存在,所以只要拿了左边的石子之后,当前局面都是必胜态,所以不可能拿左边的石子。那么只能拿右边的石子,那么无论右边拿了一定量之后,无论左边添加了多少,都是一个必败态,那么此时后手在左侧随便拿走一定数量,这个状态也还是一个必败态,显然也不成立。因此必定存在。
综上,我们知道了一定存在并且唯一,而显然是对称的,因此也满足上述性质。
现在考虑如何求解,同理。首先边界情况显然,,因为只剩下两堆一模一样的情况的时候,后手只需要模仿先手的行动对称执行就好了,这样子一定不会输,即先手必败。
接下来来大力分类讨论,为了方便,设
-
这种情况下显然只需要直接把放进去就好了,即这个区间本身就是一个必败态。所以。
-
这种情况下。这种情况下最靠左的和是相同的,意味着先手无论怎么取,后手显然可以学着它的方法取,也就意味着左右两堆中显然必然会先拿完一堆,此时后手学着拿的那一堆的石子数一定也是小于的。假设先手先拿完了最靠右的一堆,即剩下了,因为表示的是在这一段区间最左侧加入一个的堆,无论先手怎么取先手都是必败的,那么我们等价的认为先手取走了这一堆的一部分,显然后手是必胜的。假如先手先取完的是最左的一堆,同理,的含义是在最右侧加入了一堆,而,我们还是可以等价的认为先手在这一堆中取走了若干石子,而这个状态对于先手而言是必败状态,因此显然后手必胜。
-
这种情况下。这样子考虑,假设先手先拿了左边这一堆,那么假设还剩下了个石子,如果,后手把右侧的那一堆也给拿成就变成了上面的情况。如果,那么后手把最后那一堆拿成,于是又回到了这种情况,相当于这种情况递归处理。如果先手先拿的是右侧的这一堆,还是一样的,假设把它拿成了,如果,同上可以变成的情况;如果,直接把左边拿完,就变成了的定义了,先手必败;如果,把左边那堆变成,同样递归处理。
-
分析同上,。
-
。还是一样的,假设先手把其中一堆拿成了。如果,跟着先手拿成一样多的石子则又回到了这种情况。如果,则可以回到情况。否则的话对应着把另外一堆变成或者,对应着和两种情况。
而和是对称的,类似的求解即可。
那么最终只需要判断和是否相等即可判断胜负情况。
代码有点丑
#include<iostream> #include<cstdio> using namespace std; #define MAX 1010 inline int read() { int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } int n,a[MAX],L[MAX][MAX],R[MAX][MAX]; int main() { int T=read(); while(T--) { n=read(); for(int i=1;i<=n;++i)a[i]=read(); 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 x=a[j],l=L[i][j-1],r=R[i][j-1]; if(x==r)L[i][j]=0; else if((x>l&&x>r)||(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(x==l)R[i][j]=0; else if((x>l&&x>r)||(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; } puts(a[1]==L[2][n]?"0":"1"); } } -
- 1
信息
- ID
- 1635
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者