加法和乘法

加法和乘法

​ 题目链接:https://ac.nowcoder.com/acm/contest/9983/J

​ 时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

有一天牛牛和牛妹在做游戏,规则如下:
桌面上摆着n张纸牌,每张纸牌上写着一个正整数,由牛牛先手轮流执行以下操作:
1.如果桌面上只剩一张纸牌,游戏结束,这张纸牌上的数字如果是奇数则牛牛胜利,反之牛妹胜利。
2.当前行动玩家选择两张纸牌,设上面的数字分别为X,Y,接下来玩家从加法和乘法中选择一个并应用到这两个数字上,得到结果为Z,接下来将选择的两张纸牌丢弃,并拿一张新的纸牌放到桌面上,在上面写上Z。
假设双方均以最优策略行动,最后谁会赢?

输入描述:

第一行一个正整数n,代表开始的纸牌数。
第二行n个空格分隔的正整数ai代表开始纸牌上的数字。

1 ≤ n ≤ 1 0 6 , 1 ≤ a i ≤ 1 0 9 1≤n≤10^6,1≤ai≤10^9 1n1061ai109

输出描述:

如果牛牛能赢,输出NiuNiu,否则输出NiuMei。

示例1

输入

3
233 2333 23333

输出

NiuMei

示例2

输入

4
1 1 1 1

输出

NiuNiu

这是一道博弈题,一般博弈题都要打表找规律,这题可以通过分析解决。

众所周知,奇数 * 奇数=奇数,奇数 * 偶数=偶数,偶数* 偶数=偶数,奇数+奇数=偶数,奇数+偶数=奇数,偶数+偶数=偶数。

也就是说,如果剩下的数字中全是偶数,牛牛必输。所以牛牛要想获胜,就要尽量把偶数都变成奇数。

所以牛牛的最优策略是减少偶数的数量。比如 1 2 2,让1加2,就变成 3 2 ,一奇一偶,或者让2加2,就变成1 4.也是一奇一偶,所以当有偶数的时候,牛牛的最优策略是减少1个偶数。

牛妹则尽量减少奇数,最优策略是让2个奇数相加,变成1个偶数,或者让1奇与1偶相乘变成1个偶数。

比如:

当偶数的个数大于等于2时

假设

有10个奇数,2个偶数

牛牛行动后,偶数-1

有10个奇数,1个偶数

牛妹行动后,奇数-2,偶数+1

有8个奇数,2个偶数

可以看到,一回合过后偶数数量没变,奇数减少了2个,一直这样下去,牛牛肯定输了。

得出结论,偶数个数>=2时,牛牛必输。

当只有1个偶数时:

假设

有10个奇数,1个偶数

按照上面的模式之后…

有2个奇数,1个偶数

此时到牛牛行动,偶数-1

有2个奇数,0个偶数

这时,牛妹让两个奇数相加,变成一个偶数,所以最后牛妹赢了。

但这只是因为最后刚好只剩下两个奇数,如果是只剩下一个奇数,那就是牛牛赢了。

因此

结论:只有一个偶数,奇数有奇数个时,牛牛赢

当没有偶数时:

可以打表找到规律,奇数有奇数个时,牛牛输,奇数有偶数个时,牛牛赢,但要注意,n可以取1,所以

没有偶数时,且奇数的个数为偶数或者只有一个奇数时,牛牛赢

综上所述:

牛牛赢:偶数有一个且奇数个数为奇,或者没有偶数且 奇数个数为偶或只有一个奇数。

#include
#define endl '\n'
#define int long long
#define Please return
#define AC 0
using namespace std;
void fastio(){
     ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);}
signed main()
{
     
	fastio();
	int n,jishu=0;
	int oushu=0;
	cin>>n;
	while(n--)
	{
     
		int a;
		cin>>a;
		if(a&1)jishu++;
		else oushu++;
	}
	if(((jishu&1)&&oushu==1)||((!(jishu&1))&&oushu==0)||(jishu==1&&oushu==0)) cout<<"NiuNiu"<<endl;
	else cout<<"NiuMei"<<endl;
	Please AC;
}

你可能感兴趣的:(ACM题目,算法,博弈论,贪心算法)