POJ 2348 Euclid's Game

来源:互联网 发布:数据库服务启动不了 编辑:程序博客网 时间:2024/06/06 01:53

1.题目描述:点击打开链接

2.解题思路:本题需要寻找必胜态和必败态的规律。假设b>a,首先容易想到,当b是a的倍数时候,该情况下先手是必胜态。还可以想到的情况是,如果b-a<a,那么这时候因为只有这一种走法,因此必胜态和必败态一定是在相互转化,如果后者必胜,那么前者必败,反之亦然。比较难考虑的是b-a>a的情况,因为这时候可供选择的方案很多,如果暴力搜索肯定是容易超时的。这时需要进一步细致的分析。

假设有一个正整数x满足b-x*a<a,那么b-(x-1)*a>a,且b-(x-1)*a<2a。不妨设b1=b-x*a,b2=b-(x-1)*a。即我们可以得到(b1,a),(b2,a)这2种临界状态,他们都是前面分析过的,只存在一种走法的状态,而且,b2==b1+a。根据奇偶性原理不难得知,这2种状态必然是一胜一负的。亦即总是存在一种状态是必胜的,因此当b-a>a时候,一定是必胜态。这样,本题便顺利得以解决。

3.代码:

#include<iostream>#include<algorithm>#include<cassert>#include<string>#include<sstream>#include<set>#include<bitset>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<cctype>#include<list>#include<complex>#include<functional>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define me(s)  memset(s,0,sizeof(s))#define rep(i,n) for(int i=0;i<(n);i++)typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;typedef pair <ll, ll> P;int a,b;void solve(){    bool f=true;    while(1)    {        if(a>b)swap(a,b);        if(b%a==0)break;//一定是先手必胜        if(b-a>a)break;//同上        b-=a;        f=!f;    }    if(f)puts("Stan wins");    else puts("Ollie wins");}int main(){    while(~scanf("%d%d",&a,&b))    {        if(!a&&!b)break;        solve();    }}

0 0
原创粉丝点击