Hakase and Nano(博弈)


题意:有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<bits/stdc++.h>
#define ll long long
using 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)/~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值