E - 娜娜梦游仙境系列——莫名其妙的插曲
Problem Description
娜娜因为帮桃花村民们解决了一大难题而受到村民们的尊敬,不过由于娜娜还想继续探索这个神奇的世界,只好恋恋不舍地与村民告别。当娜娜离开村庄的一刻,娜娜失忆了!她不记得桃花村的一切,她不记得之前吃了很多糖果,她不记得她为了过湖而跳了半天,甚至她连自己的名字都不记得了!娜娜盲目地四处溜达,突然迎面走来了一个白马王子,他问:“你是Alice吗?”。娜娜心想:“Alice?好熟的名字啊,难道这就是我的名字吗?",便回答:”是的。请问您是?“白马王子很高兴地说:”我叫Bob,我找你找了一辈子了,没有你,我总是被父王忘记,我们回王宫吧!"于是娜娜就迷迷糊糊地被带到了王宫。
国王:“你就是Alice?怎么士别三日,你变痴呆了啊,你先和我的儿子Bob先玩一玩游戏,我看看你是不是脑子有问题。”娜娜为了证明自己脑子没问题,只好与Bob玩起了游戏。
游戏规则很简单,一开始有一个集合,集合里有n个不同的数,然后Alice(娜娜)与Bob轮流进行操作,每人都可以任意选择两个数a,b,不妨设a>b,不过要求a-b不在集合中,把a-b放入集合。如果轮到某人,无法进行任何操作,则该人输掉游戏。作为职业博弈选手,娜娜即使失忆了也能凭着身体的直觉去进行最优操作。那么问,当Alice(娜娜)与Bob都沿着最优策略进行,女士优先(即娜娜先手),最终谁会获胜?
Input
多组数据,首先是一个正整数t(t<=20),表示数据的组数
对于每组数据,首先是一个整数n(1<=n<=1,000),然后是n个整数x[i](0<x[i]<=1,000,000,000),表示集合。保证集合元素不会出现相同。
Output
对于每组数据,若Alice(娜娜)最终胜利,输出"Win"
若Bob最终胜利,输出"Lose"
若无法分出胜负,输出"Draw",(均不包括双引号,注意大小写,建议复制)
Sample Input
2 5 1 2 3 4 5 5 1 2 3 4 6
Sample Output
Lose Win
Hint
样例1,一开始无论娜娜选择哪两个元素,其差值均包括在集合中,故娜娜无法操作,Bob胜利,输出Lose
样例2,一开始娜娜只能选择1和6这两个元素,并把6-1=5放入集合中,则集合变为1,2,3,4,5,6 Bob无法操作,Alice(娜娜)胜利,输出Win
每次从集合中取两个数,然后计算着两个数着两个数的差a-b(a》b),把这个差放入集合中,直到集合无法放入,判断谁胜谁负。集合不会出现相同的元素
题解:
每次取两个数的差,放入集合中,假设,集合中只要两个数,每次取两个数的差放入集合中,在从中取两个数的差放入集合中,可以知道由集合中的数,都会是最初的两个数的最大公约数的倍数,集合能够放多少个数,则取决于集合最初最大的数,满元素的个数S=最大的数MAX/集合的最大公约数GCD,判断还可以放入多少个数的话,则times=S-集合最初有的元素的个数。(集合不会出现相同的元素,保证满集合的个数可以确定={d,2*d,...MAX},d=gcd(集合);)。所有对于N个数的集合来说,集合所能够放的数的个数也同样等于=最大的数MAX/集合的最大公约数GCD,还可以操作的次数为times=S-集合最初有的元素的个数,判断操作次数的奇偶性就可以知道谁胜谁负了的。
1 int GCD(int x,int y) /*非递归的传统GCD*/ 2 { 3 int Tmp; 4 while(y) 5 { 6 Tmp=y; 7 y=x%y; 8 x=Tmp; 9 } 10 return x; 11 } 12 int main() 13 { 14 int T,N,G_Num,Max; 15 int Num[10086]; 16 scanf("%d",&T); 17 while(T--) 18 { 19 scanf("%d",&N); 20 scanf("%d",&Num[0]); 21 G_Num=Num[0]; 22 Max=Num[0]; 23 for(int i=1;i<N;i++) 24 { 25 scanf("%d",&Num[i]); 26 G_Num=GCD(G_Num,Num[i]); /*求所有最大数的最大公约数*/ 27 if(Max<Num[i])Max=Num[i]; /*找集合中的最大数*/ 28 } 29 if((Max/G_Num-N)%2)printf("Win "); /*判断操作次数的奇偶性*/ 30 else printf("Lose "); 31 } 32 return 0; 33 }