題目大意:
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;
}
}
}