HDOJ-2177 取(2堆)石子游戏

首先判断当前状态是否为奇异状态,若是则输了。若不是赢,把当前非奇异状态转化为奇异状态有四种情况.假设当前状态为(a, b)(a <= b), t = (sqrt(5)+1) / 2,d = b - a, 要转化到的奇异状态为(ak, bk).
1 若d * t < a,则可在两石子堆中去相同数目的a - d*t个石子.
2.若a = ak, b > bk, 在第二堆石子中取b - bk个石子
3.若b = bk, a > ak,在第一堆石子中取a - ak个石子.
4.若a != b && a = bk, 在第二堆石子中取b - ak个石子.

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <cstdio>
#define maxn 1000005

using namespace std;

int pl[maxn], pr[maxn];
double t;
void Init(){

     t = (sqrt(5) + 1) / 2.0;
     for(int i = 0; i * t + i < maxn; i++){

            int fa = i * t; 
            pl[fa] = i;
            pr[fa+i] = i;
     }
}
int main(){

    //freopen("in.txt", "r", stdin);
    memset(pl, -1, sizeof(pl));
    memset(pr, -1, sizeof(pr));
    Init();

    int a, b;
    while(cin >> a >> b){

        if(a == 0 && b == 0)
          break;
        if(a > b)
          swap(a, b);
        int d = b - a;
        int h = d * t;
        if(h == a){
            cout << 0 << endl;
        }
        else{
            cout << 1 << endl;
            if(h < a)
              cout << h << " " << b - (a - h) << endl;
            if(pl[a] != -1 && b > a + pl[a])
               cout << a << " " << a + pl[a] << endl;
            if(pr[b] != -1 && a > b - pr[b])
               cout << b - pr[b] << " " << b << endl;
            if(a != b && pr[a] != -1)
              cout << a - pr[a] << " " << a << endl;
        }
    }
    return 0;
}

你可能感兴趣的:(HDOJ-2177 取(2堆)石子游戏)