取石子问题
描述
有两堆石子,两个人轮流去取.每次取的时候,只能从较多的那堆石子里取,并且取的数目必须是较少的那堆石子数目的整数倍.最后谁能够把一堆石子取空谁就算赢.
比如初始的时候两堆石子的数目是25和7
25 7 --> 11 7 --> 4 7 --> 4 3 --> 1 3 --> 1 0
选手1取 选手2取 选手1取 选手2取 选手1取
最后选手1(先取的)获胜,在取的过程中选手2都只有唯一的一种取法。
给定初始时石子的数目,如果两个人都采取最优策略,请问先手能否获胜。
关于输入
输入包含多数数据。每组数据一行,包含两个正整数a和b,表示初始时石子的数目。
输入以两个0表示结束。
关于输出
如果先手胜,输出"win",否则输出"lose"
例子输入
34 12
15 24
0 0
例子输出
win
lose
提示
假设石子数目为(a,b)且a>=b,如果[a/b]>=2则先手必胜,如果[a/b]<2,那么先手只有唯一的一种取法.
[a/b]表示a除以b取整后的值.
1 #include "stdlib.h" 2 #include <iostream> 3 #include<string> 4 #include <stdio.h> 5 using namespace std; 6 int step=0;//设定走的步数为step 7 int getmax(char[],char[]); 8 void act(char a[], char b[]); 9 void calc(char a[], char b[]); 10 int minus0(char a[], char mulb[]); 11 int getlen(char a[]); 12 void mult(char b[], char mulb[]); 13 void relist(char a[], int lto, int lfrom, char newa[]); 14 void act(char a[], char b[]) 15 { 16 step++; 17 char mula[100], mulb[100]; 18 mult(a, mula); 19 mult(b, mulb);//分别取得a,b的二倍值 20 if (!strcmp(a,b)||!strcmp(a,mulb)||!strcmp(b,mula))//取完后退出函数 21 { 22 return; 23 } 24 else if (minus0(a, mulb) || minus0(b, mula))//根据提示,当遇上a/b>2的情况,此时的步数奇偶性一定与最后步数相同 25 { 26 return; 27 } 28 else if (minus0(a, b))//只有一种取法 29 { 30 calc(a, b); 31 } 32 else if (minus0(b, a))//只有一种取法 33 { 34 calc(b, a); 35 } 36 act(a, b); 37 } 38 void calc(char a[], char b[]) 39 { 40 char newb[100]; 41 int la = strlen(a),lb=strlen(b); 42 relist(b, la, lb,newb); 43 for(int i=la-1;i>=0;i--) 44 { 45 a[i] = a[i] - newb[i]+'0'; 46 if (a[i] - '0' < 0 && i != 0) 47 { 48 a[i] += 10; 49 a[i - 1]--; 50 } 51 } 52 int peak=0; 53 for(int i=0;i<=la;i++) 54 { 55 if (a[i] != '0') 56 { 57 peak = i; 58 break; 59 } 60 } 61 for(int i=peak;i<=la;i++) 62 { 63 a[i - peak] = a[i]; 64 } 65 a[la - peak + 1] = '