【未来算算】2209 有两个年轻人

题目链接 见文件第一题

题目描述

桌子上刚开始有 n 堆棋子,第 i 堆棋子有 ai (ai>0)个棋子。
两个年轻人轮流操作。每次操作,可以从当前剩余的所有棋子堆中,选择出 棋子数量最少的 (如果有多堆棋子满足条件,则在它们中任选一堆)某一堆棋子,然后从中拿走任意数量的棋子。
要求拿走的数量不能为 0 ,不能超过这一堆所剩余的棋子数。
拿走桌子上最后一颗棋子的人获胜。
请问,在当前局面下,两个年轻人都采用最优策略,先手的人是否能够取胜?

输入格式

第一行,一个正整数 T,表示测试组数。
每组数据,第一行,一个整数 n。
接下来一行, n 个整数,ai  表示第 i 堆的棋子数。

输出格式

输出 T 行。
对每组数据,如果先手存在必胜策略,则输出 Yes
否则输出 No

样例

样例输入

2

2

1 1

1

3

样例输出

No
Yes

提示

【样例 1 解释】
第一局,先手拿走第一堆的棋子,只能拿一颗。后手拿走第二堆的棋子,后手获得胜利。
第二句,先手拿走第一堆的全部棋子,先手获得胜利。
【数据范围】
对30%的数据满足,n ≤ 18,0<ai ≤ 10
对60%的数据满足,n ≤ 2000,0<ai ≤ 1000
对100%的数据满足,0 <T ≤ 10,n ≤ 10^4,0 < ai ≤ 10^18
时间限制 1.00s
内存限制 256.00MB

题解

其实这个题只要推出结论了就很简单了,首先我们可以明确如果只有一堆,那么先拿的人只需要全部拿走就可以获胜,所以只有一堆时,先手必胜。如果不只一堆,那么我们需要统计棋子数量为1的堆数,当所有的ai=1的棋子堆都被取完后,此时谁是先手则必胜,因为i<n时,我们只要每次将当前棋子堆取至只剩一个,到最后一堆时先手取完所有棋子获胜。如果所有堆的棋子数都是1,此时若为奇数堆,则先手必胜,反之,则先手必败。

实在不理解的可以看看代码。这个题很简单,但是我写的时候sum忘记每次归零了,差点爆零了(呜呜呜),写出来提醒自己下次不要忘记。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#define maxn 10010
using namespace std;
int n,t,sum;
long long a[maxn];
inline long long read(){
	int f=1,k=0;
	char c=getchar();
	while(!isdigit(c)){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(isdigit(c)){
		k=k*10+(c-48);
		c=getchar();
	}
	return f*k;
}
int main(){
	scanf("%d",&t);
	while(t--){
		sum=0;
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			a[i]=read();
			if(a[i]==1) sum++;
		}
		if(n==1){
			printf("Yes\n");
			continue;
		}
		else{
			if(sum==n){
				if(sum%2==0){
					printf("No\n");
					continue;
				}
				else{
					printf("Yes\n");
					continue;
				}
			}
			else if(sum==0){
				printf("Yes\n");
				continue;
			}
			else{
				if(sum%2==0){
					printf("Yes\n");
					continue;
				}
				else{
					printf("No\n");
					continue;
				}
			}
		}
	}
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sin_又是被迫营业的一天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值