• E


    E - 娜娜梦游仙境系列——莫名其妙的插曲

    Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others)
    Submit Status

    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

    Submit

     题意:

      每次从集合中取两个数,然后计算着两个数着两个数的差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 }
    View Code
    转载请备注:
    **************************************
    * 作者: Wurq
    * 博客: https://www.cnblogs.com/Wurq/
    * Gitee: https://gitee.com/wurq
    **************************************
  • 相关阅读:
    Git官方推荐用书
    二叉树-补习
    POJ 2251 Dungeon Master(三维BFS)
    Codeforces 675C Money Transfers (思维题)
    HDU 1195 Open the Lock(BFS)
    HDU 1010 Tempter of the Bone(DFS+剪枝)
    POJ 1426 Find The Multiple(DFS,BFS)
    POJ 3216 Prime Path (BFS)
    POJ 3278 Catch that cow(BFS)
    UVa 572 Oil Deposits(简单DFS)
  • 原文地址:https://www.cnblogs.com/Wurq/p/4430111.html
Copyright © 2020-2023  润新知