ACM: 博弈题 poj 1067

来源:互联网 发布:mac下面的图标怎么换掉 编辑:程序博客网 时间:2024/05/21 21:38
                                     取石子游戏

 

Description

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

Input

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

Output

输出对应也有若干行,每行包含一个数字1或0,如果最后你是胜者,则为1,反之,则为0。

Sample Input

2 18 44 7

Sample Output

010
题意: 见题目.
解题思路:
        1. betty定理:
      貝蒂定理 
設a、b是正無理數且 1/a +1/b =1。記P={ [na] | n為任意的正整數},Q={ [nb] | n 為任意的正整數},則P與Q是Z+的一個劃分,即P∩Q為空集且P∪Q為正整數集合Z+。
證明:因為a、b為正且1/a +1/b=1,則a、b>1,所以對於不同的整數n,[na]各不相同,類似對b有相同的結果。因此任一個整數至多在集合P或Q中出現一次。
證明: P∩Q為空集;(反證法)假設k為P∩Q的一個整數,則存在正整數m、n使得[ma]=[nb]=k。即k < ma、nb<k+1,等價地改寫不等式為 m/(k+1)< 1/a < m/k及n/(k+1)< 1/b < n/k。相加起來得 (m+n)/(k+1) < 1 < (m+n)/k,即 k < m+n < k+1。這與m、n為整數有矛盾,所以P∩Q為空集。
證明: Z+=P∪Q;已知P∪Q是Z+的子集,剩下來只要證明Z+是P∪Q的子集。(反證法)假設Z+\(P∪Q)有一個元素k,則存在正整數m、n使得[ma]< k <[(m+1)a]、[nb]< k <[(n+1)b]。 由此得ma < k ≦[ (m+1)a]-1<(m+1)a -1,類似地有nb < k ≦[ (n+1)b]-1<(n+1)b -1。等價地改寫為 m/k < 1/a < (m+1)/(k+1)及n/k < 1/b < (n+1)/(k+1)。兩式加起來,得 (m+n)/k < 1 < (m+n+2)/(k+1),即m+n < k < k+1 < m+n+2。這與m, n, k皆為正整數矛盾。所以Z+=P∪Q。
         2. betty定理可以得到 1/A + 1/B = 1;
           首先将所有P-position打出来 (失败的序列)
           1 2                (2-1=1)
3 5 (3在前面没有) (5-3=2)
4 7 (4在前面也没有 (7-4=3)
6 10(6在前面也没有)(10-6=4)
8 13(8在前面也没有)(15-8=5)
9 15  
11 18
12 20
14 23
16 26
17 28
19 31
...............
           根据betty定理,对于1/A+1/B=1,必有
           Ua={trunc(A*k),k为正整数} Ub={trunc(B*k),k为正整数} 
Ua与Ub的并集构成正整数集且Ua于Ub不相交
           所以设某个必败态的第一项为trunc(A*k),第二项为trunc(A*k+k)=trunc((A+1)*k)
           则1/A+1/(A+1)=1,求得A为(sqrt(5)+1)/2;
代码:

#include<cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
const double root = (sqrt(double(5))+1)/2;

int n, m;

int main()
{
// freopen("input.txt","r",stdin);
 while(scanf("%d%d",&n,&m) != EOF)
 {
  if(n > m)
  {
   int t =n;
   n = m;
   m = t;
  }
  if(m ==(int)((int(n/root)+1)*(root+1)) )
   printf("0\n");
  else
   printf("1\n");
 }

 return 0;
}

 
0 0