HDU 6266 Hakase and Nano (CCPC2017杭州) 博弈论

46 篇文章 0 订阅
8 篇文章 0 订阅

http://acm.hdu.edu.cn/showproblem.php?pid=6266
题目大意: H a k a s e Hakase Hakase N a n o Nano Nano轮流对 n n n堆石子进行操作,第 i i i堆石子有 a i a_i ai个石子,每一次操作可以选取某一堆石子取走任意数量的石子(至少取走 1 1 1个),取走最后一个石子的人获胜,而 H a k a s e Hakase Hakase开启了作弊模式,也就是说他每次要做两次操作,而 N a n o Nano Nano只能做一次操作,现在问你 H a k a s e Hakase Hakase能否获胜。

思路:首先考虑 H a k a s e Hakase Hakase先手的情况,考虑 n n n堆石子的个数均为 1 1 1的情况,很容易发现此时当且仅当 n % 3 = 0 n\%3=0 n%3=0的时候, H a k a s e Hakase Hakase才会失败,以此情况进行扩展,不难发现其余的任意情况 H a k a s e Hakase Hakase先手都是必胜的(考虑 H a k a s e Hakase Hakase可以消去 1 1 1堆或 2 2 2堆,总能找到必胜的情况);现在考虑 H a k a s e Hakase Hakase后手的情况,因为已经得到了先手必败态,只要 N a n o Nano Nano经过 1 1 1次操作能把当前状态转换为先手必败态,那么 H a k a s e Hakase Hakase后手就是必败的,那么当前状态仅有两种情况:(1) n % 3 = 0 n\%3=0 n%3=0,且仅有 1 1 1堆石子个数不为 1 1 1;(2) n % 3 = 1 n\%3=1 n%3=1,且至少有 n − 1 n-1 n1堆石子的个数为 1 1 1

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<unordered_map>
#define pr pair<int,int>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

const int maxn=1e6+5;

int a[maxn];
int n,t,d;

int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d %d",&n,&d);
		int tot=0,u;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&u);
			if(u==1)
				++tot;
		}
		if(d==1)// Hakase 先手
		{
			if(tot==n&&n%3==0)
				printf("No\n");
			else
				printf("Yes\n");
		}
		else // Hakase 后手
		{
			if((n%3==0&&tot==n-1)||(n%3==1&&tot>=n-1))
				printf("No\n");
			else
				printf("Yes\n");
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值