有两个年轻人

P2209 未来算算 有两个年轻人

P4190 未来计算 有两个年轻人

题目链接:http://132.232.67.120/problem.php?id=4190

                  http://42.192.231.254/upload/42.192.231.254/20221004/20221004110927_74071.pdf

题目:

题目背景:

有人问我,发生甚么事了?

我一看,哦!原来是昨天,有两个年轻人,一个数学考150,一个物理考110,在教室里练题。

我走上前去,啪,就扔出来了一道题目,很快啊!

他们说,我这个题不好做;我说我这个好做。

他们不信!我就叫你给他们说一说,该怎么做。

题目描述:

桌子上刚开始有n堆棋子,第i堆棋子有ai()个棋子。

两个年轻人轮流操作。每次操作,可以从当前剩余的所有棋子堆中,选择出棋子数量最少的(如果有多堆棋子满足条件,则在它们中任选一堆)某一堆棋子,然后从中拿走任意数量的棋子。

要求拿走的数量不能为 0 ,不能超过这一堆所剩余的棋子数。

拿走桌子上最后一颗棋子的人获胜。

请问,在当前局面下,两个年轻人都采用最优策略,先手的人是否能够取胜?

输入格式:

第一行,一个正整数T,表示测试组数。

每组数据,第一行,一个整数n

接下来一行,n个整数ai, 表示第i堆的棋子数。

输出格式:

输出T行。

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

否则输出No

样例:

输入:

2
2
1 1
1
3

输出:

No
Yes

提示:

第一局,先手拿走第一堆的棋子,只能拿一颗。后手拿走第二堆的棋子,后手获得胜利。

第二句,先手拿走第一堆的全部棋子,先手获得胜利。

数据范围:

对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

解析:

这道题是结论题,我们可以分情况讨论。首先对于一堆棋子只有一个的情况来说,轮到那个人必定是全部拿完的,而一堆棋子有不止一个时,轮到的那个人若是不想下一个人拿到这堆棋子就可以全部拿走,若是想让下一个人拿到这堆棋子而不拿其他堆的棋子就可以将这堆棋子拿走只剩一个。

综上,情况一是n=1时先手必胜;情况二是数组内全是1,则n为奇数先手胜,n为偶数后手胜;情况三是数组内不全为1,这时1的个数为欧数先手胜,为奇数后手胜。

这里注意数据范围要开long long,还要记得多组数据要初始化,以及不要因为情况多就搞错了条件。

代码如下:

//有两个年轻人
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
const int MAXN = 10001;
​
long long t,n,num;
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()
{
t=read();
while(t--)
{
n=read();
int i;
num=0;
for(i=1;i<=n;++i)
{
a[i]=read();
if(a[i]==1)  ++num;
}
if(n==num&&n!=1)
{
num&1 ? printf("Yes\n") : printf("No\n");
continue;
}
if(n==1||num%2==0||num==0)  
{
printf("Yes\n");
continue;
}
printf("No\n");
}
return 0;
}

 

完结撒花✿✿ヽ(°▽°)ノ✿

 

 

posted @ 2022-10-04 21:29  于是开始主动营业  阅读(44)  评论(0)    收藏  举报