博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hakase and Nano(博弈)
阅读量:4135 次
发布时间:2019-05-25

本文共 1285 字,大约阅读时间需要 4 分钟。

题意:有n堆石头,每堆石头有a[i]个。H和N两个人轮流拿,每人最少拿1个。1代表H先拿,2代表N先拿。问H是否会赢。H每一回合会拿两次,但是N只能拿一次。
对于H先拿的情况,如果他可以拿(代表这个堆目前不为空),他一定会尽力改变自己现在的处境。那么什么时候他就改变不了了呢?就是拿完这一堆就没有了的时候。即这一堆的石头数目为1的时候。如果n堆石子,每堆只有一个石头,那么什么时候才是H先拿的必败态呢?就是n%30的时候。这样无论H怎么拿都不能赢。其余的时候就是H的必胜态。
对于N先拿的情况,极限情况也是石头个数为1的时候。N先拿,对于H来说,之要是N拿完之后,不是H的必败态,H就可以赢了。那就讨论N拿一次成为H必败态的情况。
①n
1,无论怎么拿,H都输。
②设石头数目为1的堆有sum个,sumn并且n%31,这样无论怎么拿,H都输。
③设石头数目为1的堆有sum个,sumn-1&&n%31,N可以把不是1的那一堆拿完,而后就是H的必败态。
④设石头数目为1的堆有sum个,sumn-1&&n%30,N把不是1的那一堆拿成1,而后就是H的必败态。
代码如下:

#include
#define ll long longusing namespace std;const int maxx=1e6+100;ll a[maxx];int n,k;inline int read() {
char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9') {
if(ch == '-') f = -1; ch = getchar(); } while('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0'; ch = getchar(); } return x * f;}int main(){
int t; t=read(); while(t--) {
n=read();k=read(); int sum=0; int sum2=0; for(int i=1;i<=n;i++) {
a[i]=read(); if(a[i]==1) sum++; if(a[i]==2) sum2++; } if(k==1) {
if(n%3==0&&sum==n) puts("No"); else puts("Yes"); } else {
int flag=1; if((sum==n-1&&n%3==0)||(n==1)||(sum==n&&n%3==1)||(sum==n-1&&n%3==1)) puts("No"); else puts("Yes"); } }}

博弈就是要冷静思考,思考两小时,写题五分钟。

努力加油a啊,(o)/~

转载地址:http://gutvi.baihongyu.com/

你可能感兴趣的文章