• 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
  • 相关阅读:
    VS编译错误:#error: Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version
    C++ STL std::copy 详解
    JavaScript:{}、new Object和Object.create的区别
    函数声明和函数表达式的区别
    Java基础重写override
    Java基础多态数组
    Java基础编译类型和运行类型(多态)
    Java基础继承的内存分析
    Java基础访问修饰符
    Java基础继承的使用
  • 原文地址:https://www.cnblogs.com/E-star/p/3450247.html
Copyright © 2020-2023  润新知