Codeforces 768E:Game of Stones

Codeforces 768E:Game of Stones

题目链接:http://codeforces.com/contest/768/problem/E

题目大意:给定$n$堆石子,初始每堆$s_i$个石子.每次可从其中一堆中取任意$x(x \leqslant s'_i)$个石子,每堆石子若之前取过$x$个则不能再取$x$个(可以取$x+t$个,其中$t \neq 0$且$x+t \leqslant s'_i$).若不能取石子则判定为输,问后手是赢还是输.

nim博弈

我们将整个博弈游戏看做由$n$个博弈游戏组成,考虑仅有一堆$s_i$个石子的情况。

设$sg[i]$为仅有一堆i个石子的胜利态级数,由于有不能取重复个数的条件限制,

故$sg[i+j]=max\{sg[i]+1|j \notin \{a_k|i=sum_{k=1}^{sg[i]}a_k$,且$a_x \neq a_y\}$.

所以$sg[i]=p$,其中$p$为将$i$划分成若干个不同整数之和的划分数。

求出$sg[i]$后,将所有堆的胜利态级数异或后即得到总游戏的胜利态级数。

代码如下:

 1 #include <iostream>
 2 using namespace std;
 3 int sg[65],k=1,n,t,ans;
 4 int main(void){
 5     for(int i=1;i<=60;++i){
 6         if(i==(k+2)*(k+1)/2)k++;
 7         sg[i]=k;
 8     }
 9     cin>>n;
10     while(n--){
11         cin>>t;
12         ans^=sg[t];
13     }
14     if(ans)cout<<"NO";
15     else cout<<"YES";
16 }

 

转载于:https://www.cnblogs.com/barrier/p/6433245.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值