题意:

给定两个非负数,可以用较小那个数的任意正整数倍数去减较大那个数,但要保证结果非负。两个人轮流操作,结果中先出现0的那个人获胜。

 

第一次做博弈题,不知如何下手。这里认真分析一下。

 

假设两个数a b,他们的大小关系无非是a>b,a<b,a==b中的一种,对本题二样前两种其实是同一种情况,第三种情况时结果已经出来了(此时轮到谁谁获胜)。

 

我们再来讨论a>ba<b)的情况,又可细分为:

b<a<2 * b (1)

a == 2 * b (2)

a >2*b (3)

对情况(1,选手没得选,只能用较小的树去减较大的数,下一个状态一定是ba%b。也就是说这种状态的出现不会影响最终结果。

情况(2,显然,也可以结束游戏了,当前选手赢了。

情况(3,此时选手可以决定下一个状态是下面状态中的一种:

a-b, b

a-2*b, b

a-3*b, b

.

.

.

a%b+b, b k-1

b, a%b k

由于两个选手必须轮流操作,因此,两相邻的状态的输赢结果一定相反。而此时,选手恰恰可以决定是到状态(k-1)还是到状态(k(状态(k-1)的下一个状态一定是状态(k),因为情况(1)),也就是说此时选手能决定自己的输赢

 

综上我们可以得到如下结论

出现下述情况之一的就可断定当前选手获胜:

1.a==b

2.a>=2*b

 

细节:如果一开始输入数据为a0,本题认为Ollie wins

import java.io.*;
import java.util.*;

class Main {
    
    static boolean firstWin;
    public static void main(String[] args) throws IOException{
        int a, b;
        Scanner sc = new Scanner(System.in);
        
        a = sc.nextInt();
        b = sc.nextInt();
        while(a != 0 || b != 0){
            firstWin = true;//初始认为Stan wins
            if(a >= b)
                get(a, b);
            else
                get(b, a);
            
            if(firstWin)
                System.out.println("Stan wins");
            else
                System.out.println("Ollie wins");
            a = sc.nextInt();
            b = sc.nextInt();
            
        }
    }
    public static void get(int a, int b){//a >= b
        if(a == b)
            return;
        if(b == 0){//边界情况,如果一开始输入是b为零,我们认为Ollie wins
            firstWin =  !firstWin;
            return;
        }
        if(a / b >= 2)
            return;
        
        firstWin =  !firstWin;
        get(b, a % b);
    }
}

 

posted on 2013-05-04 16:21 小鼠标 阅读(258) 评论(0)  编辑 收藏 引用 所属分类: 博弈

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2012年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

随笔分类(111)

随笔档案(127)

friends

最新评论

  • 1. re: 线段树
  • 是这个样子的,所以在OJ有时候“卡住”了也不要太灰心,没准真的不是自己的原因呢。
    加油,祝你好运啦!
  • --小鼠标
  • 2. re: 线段树
  • 对于编程竞赛来说,Java所需时间一般为C/C++的两倍。合理的竞赛给Java的时间限制是给C/C++的两倍。
  • --伤心的笔
  • 3. re: poj1273--网络流
  • 过来看看你。
  • --achiberx
  • 4. re: (转)ubuntu11.10无法启动无线网络的解决方法
  • 膜拜大神。。查了一个下午资料终于在这里解决了问题。。神牛说的区域赛难道是ACM区域赛。。?
  • --Hang
  • 5. re: 快速排序、线性时间选择
  • 博主,谢谢你的文章。你的方法可以很好的处理分区基准在数组中重复的情况,书上的方法遇到这种输入会堆栈溢出。书上给出了解释但给的方法貌似不简洁。
  • --lsxqw2004

阅读排行榜