zoukankan      html  css  js  c++  java
  • HDU 1525

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1525

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

    Problem Description
    Two players, Stan and Ollie, play, starting with two natural numbers. Stan, the first player, subtracts any positive multiple of the lesser of the two numbers from the greater of the two numbers, provided that the resulting number must be nonnegative. Then Ollie, the second player, does the same with the two resulting numbers, then Stan, etc., alternately, until one player is able to subtract a multiple of the lesser number from the greater to reach 0, and thereby wins. For example, the players may start with (25,7):
    25 7
    11 7
    4 7
    4 3
    1 3
    1 0
    an Stan wins.

    Input
    The input consists of a number of lines. Each line contains two positive integers giving the starting two numbers of the game. Stan always starts.
     
    Output
    For each line of input, output one line saying either Stan wins or Ollie wins assuming that both of them play perfectly. The last line of input contains two zeroes and should not be processed.

    Sample Input
    34 12
    15 24
    0 0
     
    Sample Output
    Stan wins
    Ollie wins
     
    作为一道博弈题,我这种只会套模板不会动脑筋的咸鱼只好完全听从网上题解的话,老老实实找规律……
     
    题意:
    有2个数,2个人轮流把大的数(设为a)减去小的数(设为b)的倍数(不能超过大的数),一直到有一方能把某个数减到0,该方获胜。Stans先走,问最后赢的是谁。
     
    题解:
    首先我们把这对数按(a,b)(始终假设使得a>b,这个对于实际操作时没有影响,只是方便操作)表示;
      情况①:(a,b)满足b == 0,这个时候是必败局。
      情况②:(a,b)满足a%b == 0,这个时候,便是必胜局。
      情况③:(a,b)满足a/b >= 2(但a%b != 0),那么当前操作者肯定可以把(a,b)变成(a%b,b)或者(a%b+b,b),而因为对于任意一个(a,b)要么是必胜局,要么是必败局;
          故在参赛者是最聪明最有预见性的前提下,那么他必然可以得知(a%b,b)是必胜局还是必败局;
          若(a%b,b)是必胜局,直接做(a,b)→(a%b+b,b)操作,那么对手必然只能做(a%b+b,b)→(a%b,b)操作,这样就可以使得我们得到必胜局情形。
          若(a%b,b)是必败局,那么直接做(a,b)→(a%b,b)操作,使得对手面对必败局情形,这样我们依然是必胜。
          故综合以上情况,情况③是必胜局情形。
      情况④:(a,b)满足b<a<2*b,这种情况,我们只有一种选择,就是做(a,b)→(a-b,b)操作,这时只能老老实实继续操作下去,直到遇到必败局或者必胜局为止。
     
    这样,我们便把游戏所有的情况都列举了出来,具体考虑怎么写成代码,也可以参考上面的情况写:
    ①首先保证a>b(通过if+swap);
    ②设定一个布尔类型的winner变量,winner==1代表Stan(先手)赢,winner==0代表Ollie(后手)赢;
    ③做一个while(1)的循环
      ④判断b==0?,若为真,当前操作者面对必败局,故winner=!winner,然后break;
      ⑤判断a%b==0 或者a/b >= 2 ?,若为真,则当前操作者面对了必胜局,直接break;
      ⑥剩下的情况只可能是上前列举的“情况④”,这时老老实实a-=b,swap(a,b),winner!=winner,代表当前操作者别无选择,只能按规则操作,并且下一步操作者变成对方。
    ⑦输出谁是胜者。
     
    AC代码:
     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 int a,b;
     5 bool winner;
     6 int main()
     7 {
     8     while(scanf("%d%d",&a,&b) && a!=0 && b!=0)
     9     {
    10         if(a<b) swap(a,b);
    11         winner=1;
    12         while(1)
    13         {
    14             if(b==0)
    15             {
    16                 winner=!winner;
    17                 break;
    18             }
    19             if(a%b==0 || a/b>=2) break;
    20             a-=b;
    21             swap(a,b);
    22             winner=!winner;
    23         }
    24         printf("%s wins
    ",winner?"Stan":"Ollie");
    25     }
    26 }
  • 相关阅读:
    mysql的主从复制是如何实现的
    Innodb的索引
    PHP 五大运行模式
    nginx 与PHP之间是怎么交互的? Nginx与PHP通信的两种方式 unix socket和tcp socket
    识别身份证中的籍贯、出生年月、性别-http://www.cnblogs.com/huxj/archive/2010/08/01/1789843.html转!
    mysql大数据分表后查询
    19. HTTP协议二:HTTP请求与响应、常见状态码
    18. HTTP协议一:概述、原理、版本、请求方法
    17. 接口定义
    16. Django基础数据访问
  • 原文地址:https://www.cnblogs.com/dilthey/p/7512023.html
Copyright © 2011-2022 走看看