题目大意:
A和B做游戏规则是:
首先给定了N0,A选择一个数a(N0≤a≤N0^2),B选择一个数b,保证a/b 是一个素数的正数次幂。下一次游戏,将b作为N0,继续;
若A能选到1990,则A赢,若B能选到1则B赢。A,B走的都是最优策略,给定N0问谁能赢
解题思路:
说实话,完全不想写找规律的题,这题找了一个多小时。。。
就算是找规律也是博弈,找到必胜点就行,假若我们想A必胜:
1、N0 = 45~1990,(44*44 < 1990 ),这时候A能直接取1990,所以A必胜。
2、如果大于1990,因为是最优策略,那么A一定可以选到某个数S用唯一分解定理分解后,是某个数的幂次方和其余素数的成绩,也就是说B选择的数一定比S小,那么迟早会到满足1条件的数,所以这一部分也是A必胜。
3、剩下的范围,只能几乎一个一个算,但是,根据题意来看,7以下A绝对不可能必胜,算了一下8,NO = 8的话,A只能取8~64之间的某个数,依然假定A必胜,那么就是说取的数S一定比8要大,逼近1和2的策略,那么S可以取4 * 3 * 5,这样B只能取3*5才能使a/b使一个素数的整数次幂,那么下一轮的N0 = 15,同样,在15~255的范围里,我们要寻找比分解后一部分比15大的数,而有2 * 3 * 5 *7 < 255,那么B最小要取2*3*5=30.etc如此来看是可以逼近到1、2策略的,那么我们如果在随便假设某些大于8的N0,发现也是这样,那么几乎已经可以说明是这样了,也就是N0 > 8时也可以使得A必胜。
4、N0 = 1, 2, 3, 4, 5,只要取这些数,那么B绝对可以直接取1,因为这些N0都是素数的幂次方。
5、N0 = 6,有点难受,题目中要求说是会有无限循环的情况,这玩意我一开始怎么也想不明白,在6~36的范围内,找不到完全可以一直逼近·1、2策略的点,取的不当就会输,但还是有这样的点使其赢不了也输不掉,例如,28 = 4 * 7,B会取7,那么下一轮A不想输的话,A不会选择两个数都小于5的,因为这样由于策略4就输了,A可以选择48 = 2 * 3 * 8,这样B只能取6,又回来了,同理7也是这样。
PS:
真正需要算的其实只有6,7这种无限循环的点,A绝对不可能取单个素数,这样就会输掉,所以任何策略A都只能取素数乘积,但是在6,和7 的情况下,完全没有这种乘积使其必胜,而5种策略中4中B都是被动的,完全看A怎么选,也就是说万不得已,A是不会输的。SB游戏。。。。
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
//#define maxd 1010
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define mc(x, y) memcpy(x, y, sizeof(x))
#define ms(x,y) memset(x,y,sizeof(x))
#define rep(i,n) for(int i=0;i<(n);i++)
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
#define PI pair<int,int>
//#define mapp make_pair
#define FI first
#define SE second
#define IT iterator
#define PB push_back
#define Times 10
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int > pce;
//#define N 100
const double eps = 1e-10;
const double pi = acos(-1.0);
const ll mod = 1e9+7;
const int inf = 0x3f3f3f3f;
//const ll INF = (ll)1e18+300;
const int maxd = 1000 + 10;
const int maxx = 10100;
int main() {
int n;
while(cin >> n) {
if(n < 6) {
cout << "The stranger will win!!" << endl;
}
else if (n == 6 || n == 7) {
cout << "It's an endless game!!" << endl;
}
else {
cout << "I will win!!" << endl;
}
}
}