zoukankan      html  css  js  c++  java
  • HDU 2177——威佐夫博弈

    题目:

    Description

    有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。如果你胜,你第1次怎样取子? 

    Input

    输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,且a<=b。a=b=0退出。

    Output

    输出也有若干行,如果最后你是败者,则为0,反之,输出1,并输出使你胜的你第1次取石子后剩下的两堆石子的数量x,y,x<=y。如果在任意的一堆中取走石子能胜同时在两堆中同时取走相同数量的石子也能胜,先输出取走相同数量的石子的情况.

    Sample Input

    1 2
    5 8
    4 7
    2 2
    0 0

    Sample Output

    0
    1
    4 7
    3 5
    0
    1
    0 0
    1 2
    题意:如上
    分析:
       威佐夫博弈进阶,主要是当判断为必胜局面时,判断(a,b)的大小,然后根据这个从N态—>P态,输出走过之后的剩余石子数。
     1 #include<cstdio>
     2 #include<cmath>
     3 int main()
     4 {
     5     int a,b,k;
     6     double eps=(1+sqrt(5.0))/2.0;
     7     while(scanf("%d%d",&a,&b)==2&&(a||b))
     8     {
     9         int t;
    10         if(a>b)
    11         {
    12             t=a;
    13             a=b;
    14             b=t;
    15         }
    16         k=b-a;
    17         if(int(k*eps)==a)
    18             printf("0
    ");
    19         else
    20         {
    21             printf("1
    ");
    22             for(int i=1;i<=a;i++)
    23             {
    24                 int n,m;
    25                 n=a-i;
    26                 m=b-i;
    27                 if(n>m)
    28                 {
    29                     t=n;
    30                     n=m;
    31                     m=t;
    32                 }
    33                 k=m-n;
    34                 if(int(k*eps)==n)
    35                     printf("%d %d
    ",n,m);
    36             }
    37             for(int i=b-1;i>=0;i--)
    38             {
    39                 int n,m;
    40                 n=a;
    41                 m=i;
    42                 if(n>m)
    43                 {
    44                     t=n;
    45                     n=m;
    46                     m=t;
    47                 }
    48                 k=m-n;
    49                 if(int(k*eps)==n)
    50                     printf("%d %d
    ",n,m);
    51             }
    52         }
    53     }
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    2021,6,10 xjzx 模拟考试
    平衡树(二)——Treap
    AtCoder Beginner Contest 204 A-E简要题解
    POJ 2311 Cutting Game 题解
    Codeforces 990G GCD Counting 题解
    NOI2021 SDPTT D2T1 我已经完全理解了 DFS 序线段树 题解
    第三届山东省青少年创意编程与智能设计大赛总结
    Luogu P6042 「ACOI2020」学园祭 题解
    联合省选2021 游记
    Codeforces 1498E Two Houses 题解 —— 如何用结论吊打标算
  • 原文地址:https://www.cnblogs.com/forwin/p/4890439.html
Copyright © 2011-2022 走看看