找規律·Number Game ZOJ - 3346

題目大意:

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;
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章