zoukankan      html  css  js  c++  java
  • 博弈论 Nim博弈 反Nim博弈 SG函数

    Nim游戏 HDU1846

    若各堆石子异或和为不为零,则先手胜 ,后手当且仅当异或和为零时取胜

    此题问要想先手取胜第一步的取法,考虑到上述引理,只需遍历一遍石子找到异或和的最高位匹配的个数。

    int a[105];
    
    int main() {
        int m;
        while (scanf("%d", &m),m) {
            int cnt = 0;
            for (int i = 0; i < m; i++) scanf("%d", &a[i]);
            int nim = a[0];
            for (int i = 1; i < m; i++) nim ^= a[i];
            if (nim == 0) printf("0\n");
            else {
                int tmp = 0;
                while (nim) nim /= 2, tmp++;
                tmp--;
                for (int i = 0; i < m; i++) if (a[i] & (1 << tmp)) cnt++;
                printf("%d\n", cnt);
            }
        }
        return 0;
    }
    View Code

    HDU 1848

    在上题的基础上取法只许取斐波那契数列的大小

    考虑SG函数模板

    int f[50], sg[1005], mex[1005];
    int getSG(int n) {
        sg[0] = 0;
        for (int i = 1; i <= n; i++) {
            memset(mex, 0, sizeof mex);
            for (int j = 1; f[j] <= i; j++) {
                mex[sg[i - f[j]]] = 1;
            }
            for (int j = 0;; j++) if (!mex[j]) {
                sg[i] = j;
                break;
            }
        }
        return sg[n];
    }
    
    int main() {
        int n, m, p;
        f[1] = 1, f[2] = 2;
        for (int i = 2; f[i] <= 1005; i++) {
            f[i+1] = f[i] + f[i - 1];
        }
        while (scanf("%d%d%d", &n, &m, &p),n||m||p) {
            if (getSG(n) ^ getSG(m) ^ getSG(p)) printf("Fibo\n");
            else printf("Nacci\n");
        }
        return 0;
    }
    View Code

    HDU1907 

    反Nim游戏,最后一步取的人败

    先手必胜的情况有两种,只要是这两种情况之一就为先手必胜,

    一:各堆石子数目异或结果不为零,且至少有一堆石子数目大于1

    二:各堆石子数目异或结果为零,且所有堆石子数目均为1;

    int a[50];
    
    int main() {
        int T;
        int n;
        int ans;
        scanf("%d", &T);
        while (T--) {
            int rich = 0;
            scanf("%d", &n);
            for (int i = 0; i < n; i++) {
                scanf("%d", &a[i]);
                if (a[i] > 1) rich++;
                if (!i) ans = a[i];
                else ans ^= a[i];
            }
            if (ans == 0 && rich == 0) printf("John\n");
            else if (ans && rich) printf("John\n");
            else printf("Brother\n");
        }
    }
    View Code

     

  • 相关阅读:
    spring3.2以后的cglib的jar包问题
    maven入门程序(二)
    maven安装配置(myeclipse)(一)
    spring中得到servletContext对象方法
    ftp上传java代码
    FileZilla ftp服务器安装
    spring junit参数
    说一说Servlet的生命周期?
    Servlet API中forward()与redirect()的区别?
    request.getAttribute()和 request.getParameter()有何区别?
  • 原文地址:https://www.cnblogs.com/hznumqf/p/12644132.html
Copyright © 2011-2022 走看看