SG函数题目

时间:2023-03-08 17:37:21
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");
}
}
}
}

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();
}
}
}