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

 

 

 

你可能感兴趣的:(函数)