“纽劢科技杯”第十六届同济大学程序设计竞赛暨上海邀请赛同步赛 J-张老师的游戏

传送门

题目描述

    在空闲时间,张老师习惯性地和菜哭武玩起了取石子游戏,这次的游戏规则有些不同,在他们面前有n堆石子,其中,第i堆石子的个数为a[i],现在制定规则如下:
    从张老师开始,两个人轮流取石子,每次可以从任意一堆中取走x个石子,其中x必须严格小于这堆石子的总数并且能够被这堆石子的个数整除,谁先无法继续取走石子就算失败!
    例如,只有一堆石子,个数为6,张老师首先可以取走的石子个数为1,2或者3个。
    现在给定n堆石子每一堆的石子数,张老师希望你帮他确定在双方最优策略下他能否赢得游戏。
链接: https://acm.nowcoder.com/acm/contest/637/J
来源:牛客网

输入描述:

    第一行一个整数n(1<=n<=100,000)
    第二行n个整数,分别代表每一堆石头的个数,保证所有数据为小于等于10
9
的正整数

输出描述:

输出一行,Win或者Lose,表示张老师能否获得胜利
示例1

输入

3
2 2 1

输出

Lose
示例2

输入

2
2 9

输出

Win

博弈,后继状态是$n-a_{i}$ $a_{i}$表示除n外的其他因子
打表发现SG函数是该数质因子里有多少个2
#include <bits/stdc++.h>
using namespace std;

const int maxn = 1010;
int SG[maxn], S[maxn], f[maxn];

void getSG(int n) {
    S[1] = 0;
    for (int i = 2; i <= n; i++) {
        memset(S, 0, sizeof(S));
        int cnt = 0;
        int temp = i;
        f[cnt++] = 1;
        for (int j = 2; j < temp; j++) {
            if (temp % j == 0) {
                f[cnt++] = j;
            } 
        }
        sort(f, f + cnt);
        for (int j = 0; j < cnt; j++) {
            S[SG[i-f[j]]] = 1;
        }
        for (int j = 0; ; j++) {
            if (!S[j]) {
                SG[i] = j;
                break;
            }
        }    
    }   
}
int sg(int x) {
    int ret = 0;
    while (x % 2 == 0) ret++, x /= 2;
    return ret;
}

int main() {
   // getSG(1000);
   // for (int i = 1; i <= 500; i++) cout << SG[i] << ",";
    int n;
    scanf("%d", &n);
    int flag = 0;
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        flag ^= sg(x);
    }
    if (flag) puts("Win");
    else puts("Lose");
    return 0;
}
View Code
 
       
      
 

猜你喜欢

转载自www.cnblogs.com/Mrzdtz220/p/10781370.html
今日推荐