HDU 1517 A Multiplication Game(SG博弈变形)

A Multiplication Game

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5097    Accepted Submission(s): 2896


Problem Description
Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 to 9. Stan always starts with p = 1, does his multiplication, then Ollie multiplies the number, then Stan and so on. Before a game starts, they draw an integer 1 < n < 4294967295 and the winner is who first reaches p >= n.
 

Input
Each line of input contains one integer number n.
 

Output
For each line of input output one line either 

Stan wins. 

or 

Ollie wins.

assuming that both of them play perfectly.
 

Sample Input
  
  
162 17 34012226
 

Sample Output
  
  
Stan wins. Ollie wins. Stan wins.
 

Source
 

懂SG函数的话,只需要注意,这个啃爹的东西为了防止大量重复的子计算,我开了1e7大的数组然后就过了,开个5e6大的数组还超时,我只能呵呵了
代码没有任何可以多解释的,当然前提是你知道SG函数,不知道的话,建议去学习学习
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;
const int MAXM = 10 + 5;
const int MAXN = 50 + 5;
const int MAXMM = 1e7 + 5;
int F[MAXM];
int SG[MAXMM];
LL n;
int getSG(LL x){
    int Hash[MAXN] = {0};
    int i;
    for(i = 0;i < 8;i ++){
        if(x >= n) break;
        int a;
        if(x * F[i] < MAXMM){
            if(SG[x * F[i]] == -1){
                a = SG[x * F[i]] = getSG(x * F[i]);
            }

            else{
                a = SG[x * F[i]];
            }
        }
        else{
            a = getSG(x * F[i]);
        }
        Hash[a] = 1;
    }
    for(i = 0;;i ++){
        if(!Hash[i]){
            return i;
        }
    }

}


int main(){

    for(int i = 2;i <= 9;i ++){
        F[i - 2] = i;
    }
    while(~scanf("%lld", &n)){
        memset(SG, -1,sizeof(SG));
        puts(getSG(1) ? "Stan wins." : "Ollie wins.");
    }
    return 0;
}


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>