SG函数题目

HDU Fibonacci again and again

思路:

把整个游戏看成三个子游戏,然后求游戏的和

关键理解g(x) = mex(g(y), y€f(x)) , f(x)表示由x点可达的点, 

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public int[] fib = new int[20];
    public boolean[] vt = new boolean[20];
    public static int[] g = new int[1002];
    
    public void init() {
        fib[1] = 1; fib[2] = 2;
        for (int i = 3; i < 20; ++i) {
            fib[i] = fib[i - 1] + fib[i - 2];
        }
    }
    public void dfsSG() {
        //首先找出确定的点一般为0点
        g[0] = 0; g[1] = 1;
        for (int i = 2; i <= 1000; ++i) {
            Arrays.fill(vt, false);
            //然后枚举g(y)标记, g(x) = mex(g(y), y 属于 F(x));
            for (int j = 1; fib[j] <= i; ++j) {
                vt[g[i - fib[j]]] = true;
            }
            //mex()过程
            for (int j = 0; j <= 1000; ++j) {
                if (!vt[j]) {
                    g[i] = j;
                    break;
                }
            }
        }
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Main main = new Main();
        main.init(); main.dfsSG();
        int m, n, p;
        while (in.hasNext()) {
            m = in.nextInt();
            n = in.nextInt();
            p = in.nextInt();
            if (m == 0 && n == 0 && p == 0) break;
            if ((g[m] ^ g[n] ^ g[p]) != 0) {
                System.out.println("Fibo");
            } else {
                System.out.println("Nacci");
            }
        }
    }
}
View Code

  HDU  S-Nim

思路:同上。。只是每一步的策略不同罢了。。

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static Scanner in = new Scanner(System.in);
    public static int[] s;
    public static int[] g = new int[10001];
    /*
     * 注意vt的取值,我们只要的最大之只要是s的大小 + 1即可。
     * 因为我们最后往后走k不,如果这k个得到的是0-k那么我们的取值就是k+1
     * 这是最大的了
     */
    public static boolean[] vt = new boolean[107];
    
    public static int k;
    public static void dfsSG() {
        g[0] = 0; 
        for (int i = 1; i <= 10000; ++i) {
            Arrays.fill(vt, false);
            for (int j = 0; j < k; ++j) {
                if (i - s[j] < 0) break;
                vt[g[i - s[j]]] = true;
            }
            for (int j = 0; j <= 107; ++j) {
                if (!vt[j]) {
                    g[i] = j;
                    break;
                }
            }
        }
    }
    public static void main(String[] args) {
        
        while (in.hasNext()) {
            k = in.nextInt();
            if (k == 0) break;
            s = new int[k];
            for (int i = 0; i < k; ++i) s[i] = in.nextInt();
            Arrays.sort(s);
            dfsSG();
            int m = in.nextInt();
            while ((m--) != 0) {
                int sz = in.nextInt();
                int ans = 0;
                for (int i = 0; i < sz; ++i) {
                    int idx = in.nextInt();
                    ans ^= g[idx];
                }
                if (ans == 0) {
                    System.out.print("L");
                } else {
                    System.out.print("W");
                }
            }
            System.out.println();
        }
    }
}
View Code
原文地址:https://www.cnblogs.com/E-star/p/3450247.html