[博弈]Euclid's Game
Euclid's Game
Description
Two players, Stan and Ollie, play, starting with two natural numbers. Stan, the first player, subtracts any positive multiple of the lesser of the two numbers from the greater of the two numbers, provided that the resulting number must be nonnegative. Then Ollie, the second player, does the same with the two resulting numbers, then Stan, etc., alternately, until one player is able to subtract a multiple of the lesser number from the greater to reach 0, and thereby wins. For example, the players may start with (25,7):
25 7
11 7
4 7
4 3
1 3
1 0
an Stan wins.
Input
The input consists of a number of lines. Each line contains two positive integers giving the starting two numbers of the game. Stan always starts.
output
Examples
Input
34 12 15 24 0 0
Output
Stan wins Ollie wins
正确解法:
辗转相除法:
给定两个整数 a和b ,两个人轮流从较大的数字中减去较小的数字的整数倍。若其中一个数字变为0,则这个人就赢了。
首先保证 a<b 因为这两个人决策跟 a,b 的位置没有任何关系,有关系的只是他们的大小。
这样就分为两个情况:
1. b-a<a
2. b-a>a
若是第一种情况,那就不用写了,直接模拟看最后是谁赢了。
若是第二种情况:两个人都非常聪明,分为两种情况:
把 b 直接减到 比a还小的状况,那就变成了 1.的情况,之后的结果可能是赢,也可能是输。
把 b 减到 b>a 的情况,那么下一人必须作出 b=b-a 的决策。从而变成 1.的情况。
要不就直接到达情况,要不就多一步到达情况。
那么我们就可以确定这个人刚开始必胜。
1 if(b%a==0) break; 2 if(b-a>a) break;
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<map> 6 #include<set> 7 #include<vector> 8 #include<queue> 9 #include<algorithm> 10 #include<cmath> 11 using namespace std; 12 typedef long long ll; 13 const int inf=0x7fffffff; 14 const int N=1000000+100; 15 const int M=9999999; 16 const ll mod=1000000000+7; 17 18 int main() 19 { 20 ll a,b; 21 while(scanf("%lld %lld",&a,&b)&&a&&b) 22 { 23 int f=1; 24 while(true) 25 { 26 if(a>b) swap(a,b); 27 if(b%a==0) break; 28 if(b-a>a) break; 29 b=b%a; 30 f=!f; 31 } 32 if(f) cout<<"Stan wins"<<endl; 33 else cout<<"Ollie wins"<<endl; 34 35 } 36 37 38 return 0; 39 }