【牛客 - 373A】翻硬币问题(博弈,结论,分析)

题干:

链接:https://ac.nowcoder.com/acm/contest/373/A
来源:牛客网
 

Alice和Bob正在玩一个很经典的游戏。

有 n n个硬币初始时全部正面朝上,每一轮Alice必须选择其中任意的恰好 m m枚硬币并将它们全部翻转,如果若干轮翻转后所有硬币全部反面朝上,那么Alice就赢得了游戏。

假设我们认为每枚硬币只有正面朝上和反面朝上两种状态且只考虑 m m为偶数的情况,问题会比较简单。

但是出题人希望这道题更毒瘤一些,所以他增加了一条规则:Bob在整个游戏中可以有一次机会使坏--在Alice某一轮翻转完之后,偷偷选择任意硬币并将它翻转。

为了不让Alice赢得游戏,Bob会采取最优的策略。

现在给定 n n和 m m,请问Alice是否可以赢得游戏?

注意:

  1. Bob虽然可以在任何轮翻转之后使坏,但是在整个游戏中只有一次这样的机会。也就是说,如果在某一轮之后使用了这个机会,那么以后都不能再使用。
  2. 轮次可以认为是无限的,只要在任何一轮翻转后所有硬币全部反面朝上,Alice就立即赢得游戏胜利,Bob即使没有用掉使坏的机会也不能再偷偷翻转硬币。

输入描述:

 

每个输入文件有多个测试样例。

第一行一个整数 T(T≤30000) T(T≤30000)--测试样例个数。

然后 T T行,每行两个整数 n n和 m m (1≤m≤n≤109,m是偶数) (1≤m≤n≤109,m是偶数)--硬币的数量和每一轮翻转硬币的数量。其中第 i+1 i+1行表示第 i i个样例。

输出描述:

 

输出 T T行,第 i i行输出第 i i个测试样例的答案。

如果Alice可以赢得游戏输出“Yes”,否则输出“No”,请注意区分大小写。

示例1

输入

复制

2
2 2
8 6

输出

复制

Yes
No

说明

对于第一个样例,Alice直接一轮翻转全部两个硬币就可以赢得游戏。

对于第二个样例,Bob如果在第一轮结束后将任意一枚反面朝上的硬币翻转,之后Alice无论怎样翻转硬币也永远不能使得所有硬币全部反面朝上。

解题报告:

   如果要赢,只能第一次就翻出结果来,否则就输。作者:lililalala
证明:
一回合不能直接翻转所有硬币,因为m是偶数,所以只需要讨论n的奇偶性。
(1)n是奇数
某回合结束后所有硬币反面朝上可以等价于所有硬币都被翻转了奇数次。假设可以达成,那么
该回合后所有回合总翻转次数一定要为奇数(因为奇数个奇数相加是奇数)
然而m是偶数,即使在不使坏的情况下,无论翻转多少个回合,总翻转次数也一定是偶数,
所以在这种情况下是不可能赢得游戏的.答案是No
(2)n是偶数
同理,完成时所有硬币都一定要被翻转了奇数次,但是n是偶数,所以总翻转次数一定要为偶
数,在不被使坏的情况下,至少有可能完成,但是除去n=m的情况外,只要在第一回合后立即
被使坏,不管翻转哪一个硬币,都会使得总翻转次数由总是偶数变成总是奇数,和n为奇数
时原理相同,也不可能赢得游戏,答案是No
结论: n=m时答案是Yes,否则答案是No

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
ll n,m;
int main()
{
	int t;
	cin>>t;
	while(t--) {
		scanf("%lld%lld",&n,&m);
		if(n == m) puts("Yes");
		else puts("No");
	}

	return 0 ;
 }

 

你可能感兴趣的:(牛客网,博弈问题)