找规律·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;
        }
    }
}

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