取(2堆)石子游戲(威佐夫博弈)

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

解題思路:

這題徹底考察了對威佐夫博弈的掌握程度。詳見http://blog.csdn.net/userluoxuan/article/details/38336287

AC代碼:

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 500005;
int a[maxn], b[maxn], pos = 0;
void Func()
{
    for(int i = 0;;i++)
    {
        a[i] = (int)(i * ((sqrt(5.0) + 1) / 2));
        b[i] = a[i] + i;
        if(b[i] > 1000000)
        {
            pos = i;
            break;
        }
    }
}
int Find(int num)
{
    int low = 0, high = pos, mid;
    while(high >= low)
    {
        mid = (high + low) / 2;
        if(a[mid] == num)
            return mid;
        if(a[mid] > num)
            high = mid - 1;
        if(a[mid] < num)
            low = mid + 1;
    }
    return -1;
}
int Find2(int num)
{
    int low = 0, high = pos, mid;
    while(high >= low)
    {
        mid = (high + low) / 2;
        if(b[mid] == num)
            return mid;
        if(b[mid] > num)
            high = mid - 1;
        if(b[mid] < num)
            low = mid + 1;
    }
    return -1;
}
int main()
{
    int m, n;
    Func();
    while(scanf("%d%d", &m, &n) && m && n)
    {
        int k = n  - m;
        if((int)(k * ((sqrt(5.0) + 1) / 2)) == m)
            printf("0\n");
        else
        {
            printf("1\n");
            printf("%d %d\n", a[n - m], b[n - m]);
            int j = Find(m);
            if(j >= 0 && n > b[j])
                    printf("%d %d\n", a[j], b[j]);
            if(j < 0)
            {
                int l = Find2(m);
                printf("%d %d\n", a[l], m);
            }
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章