小西快乐水

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

数论只会GCD

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

题目描述

小西买了一堆肥宅快乐水和肥宅快乐茶,准备和室友比谁更肥宅。

快乐水有A瓶,快乐茶B瓶。

小西和室友的规则是这样的:

1. 小西先手,轮流到每个人的回合,每个回合只能喝剩余数量较多的饮料

2. 满足规则1的同时,每次只能喝另一种饮料剩余数量的正整数倍

3. 满足1、2的同时,不能超额喝饮料,也就是说剩下2瓶的时候不能喝大于2瓶的数量。

4. 每个人在自己的回合如果能喝完剩下的其中一种饮料,那么就获得胜利。

例如A=10,B=2。

小西只能喝快乐水,且只能喝2/4/6/8/10瓶快乐水。小西可以喝10瓶快乐水直接获得胜利。

小西和室友都是肥宅,所以他们都会才采取为了胜利最优的行动。

现在请你判断小西是否能赢得胜利。

输入描述:

 

第一行输入一个整数T,表示有T组数据

接下来T行,每行为一组数据,每行有两个正整数表示A和B的初始数量

1≤T≤500,1≤A,B≤10121≤T≤500,1≤A,B≤1012

输出描述:

对于每组数据,若小西可以获得胜利则输出一行“wula”,否则输出一行“mmp”,不需要输出引号

示例1

输入

复制

2
20 18
10 4

输出

复制

mmp
wula

 解题思路:

输入两个数a,b。假设a较大

  1. a或b为0,或者a==b,则先手一定胜
  2. a>=2b,那么a先手一定获胜,这个时候a和b之间的关系可以表示为a=nb+k(n>=2,k>=0),先手的人可以使a变成a=b①或者是a=b+k②;
    假设a=b+k是必输态,那么对手下一步一定是让a再减去b,他让a变成了k,所以我可以直接使a=k。
    假设a=k是必输态,那么a=b+k一定是必胜态,我可以直接使a=b+k从而获胜。
  3. b<a<2b这个时候就需要递归判断了,不断的相减,直到出现可以确定必胜的状态(就是第1,2中的两种情况),但是因为不确定此时的状态是属于我的还是对手的,所以在循环的时候就需要加标记判断是谁在操作。
#include <bits/stdc++.h> 
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define res register int

bool dfs(ll a,ll b,bool flag){
	if(a<b) swap(a,b);
	if(a==b||0==a||0==b||a>=2*b){
		if(flag) return true;
		else return false;
	}
	return dfs(a-b,b,!flag);	
}


int main()
{
	int T;
	scanf("%d",&T);
	while(T--){
		ll a,b;
		scanf("%lld%lld",&a,&b);
		if(a<b) swap(a,b);
		if(a==b||0==a||0==b||a>=2*b){
			printf("wula\n");
			continue;
		}
		if(dfs(a,b,true)) printf("wula\n");
		else printf("mmp\n");
 	}	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41755258/article/details/86651908