Skip to content

Commit 576b5ea

Browse files
committed
modify code
1 parent 12a9748 commit 576b5ea

File tree

7 files changed

+325
-0
lines changed

7 files changed

+325
-0
lines changed

src/class095/Code01_BashGame.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package class095;
2+
3+
// 巴什博弈
4+
// 一共有n颗石子,两个人轮流拿,每次可以拿1~m颗石子
5+
// 拿到最后一颗石子的人获胜,根据n、m返回谁赢
6+
public class Code01_BashGame {
7+
8+
public static String bashGame(int n, int m) {
9+
return n % (m + 1) == 0 ? "后手" : "先手";
10+
}
11+
12+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package class095;
2+
3+
// 质数次方版取石子
4+
// 一共有n颗石子,两个人轮流拿
5+
// 每次可以拿 p的k次方 颗石子,p是质数、k是自然数
6+
// 拿到最后一颗石子的人获胜,根据n、m返回谁赢
7+
// 如果先手赢,返回"October wins!"
8+
// 如果后手赢,输出"Roy wins!"
9+
// 测试链接 : https://www.luogu.com.cn/problem/P4018
10+
// 请同学们务必参考如下代码中关于输入、输出的处理
11+
// 这是输入输出处理效率很高的写法
12+
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
13+
14+
import java.io.BufferedReader;
15+
import java.io.IOException;
16+
import java.io.InputStreamReader;
17+
import java.io.OutputStreamWriter;
18+
import java.io.PrintWriter;
19+
import java.io.StreamTokenizer;
20+
21+
public class Code02_PickStones {
22+
23+
public static int t, n;
24+
25+
public static void main(String[] args) throws IOException {
26+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
27+
StreamTokenizer in = new StreamTokenizer(br);
28+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
29+
in.nextToken();
30+
t = (int) in.nval;
31+
for (int i = 0; i < t; i++) {
32+
in.nextToken();
33+
n = (int) in.nval;
34+
out.println(compute(n));
35+
}
36+
out.flush();
37+
out.close();
38+
br.close();
39+
}
40+
41+
public static String compute(int n) {
42+
return n % 6 == 0 ? "Roy wins!" : "October wins!";
43+
}
44+
45+
}

src/class095/Code03_NimGame.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package class095;
2+
3+
// 尼姆博弈
4+
// 一共有 n 堆石头,两人轮流进行游戏
5+
// 在每个玩家的回合中,玩家需要 选择任一 非空 石头堆,从中移除任意 非零 数量的石头
6+
// 如果不能移除任意的石头,就输掉游戏
7+
// 返回先手是否有必胜策略
8+
// 测试链接 : https://leetcode.cn/problems/game-of-nim/
9+
public class Code03_NimGame {
10+
11+
public boolean nimGame(int[] piles) {
12+
int eor = 0;
13+
for (int num : piles) {
14+
eor ^= num;
15+
}
16+
return eor != 0;
17+
}
18+
19+
}

src/class095/Code04_AntiNim.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package class095;
2+
3+
// 反尼姆游戏
4+
// 桌子上有n堆石子,小约翰和他的哥哥轮流取石子
5+
// 每个人取的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不取
6+
// 我们规定取到最后一粒石子的人算输
7+
// 测试链接 : https://www.luogu.com.cn/problem/P4279
8+
// 请同学们务必参考如下代码中关于输入、输出的处理
9+
// 这是输入输出处理效率很高的写法
10+
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
11+
12+
import java.io.BufferedReader;
13+
import java.io.IOException;
14+
import java.io.InputStreamReader;
15+
import java.io.OutputStreamWriter;
16+
import java.io.PrintWriter;
17+
import java.io.StreamTokenizer;
18+
19+
public class Code04_AntiNim {
20+
21+
public static int MAXN = 51;
22+
23+
public static int[] stones = new int[MAXN];
24+
25+
public static int t, n;
26+
27+
public static void main(String[] args) throws IOException {
28+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
29+
StreamTokenizer in = new StreamTokenizer(br);
30+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
31+
in.nextToken();
32+
t = (int) in.nval;
33+
for (int i = 0; i < t; i++) {
34+
in.nextToken();
35+
n = (int) in.nval;
36+
for (int j = 0; j < n; j++) {
37+
in.nextToken();
38+
stones[j] = (int) in.nval;
39+
}
40+
out.println(compute());
41+
}
42+
out.flush();
43+
out.close();
44+
br.close();
45+
}
46+
47+
public static String compute() {
48+
int eor = 0, sum = 0;
49+
for (int i = 0; i < n; i++) {
50+
eor ^= stones[i];
51+
sum += stones[i] == 1 ? 1 : 0;
52+
}
53+
if (sum == n) {
54+
return (n & 1) == 1 ? "Brother" : "John";
55+
} else {
56+
return eor == 0 ? "Brother" : "John";
57+
}
58+
}
59+
60+
}

src/class095/Code05_PickCakes.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package class095;
2+
3+
// 拿蛋糕
4+
// 有a块草莓蛋糕,有b块芝士蛋糕,两人轮流拿蛋糕
5+
// 每次不管是谁只能选择在草莓蛋糕和芝士蛋糕中拿一种
6+
// 拿的数量在1~m之间随意,谁先拿完最后的蛋糕谁赢
7+
// 返回先手赢还是后手赢
8+
// 来自真实大厂笔试,没有在线测试,对数器验证
9+
public class Code05_PickCakes {
10+
11+
public static int MAXN = 151;
12+
13+
public static String[][][] dp = new String[MAXN][MAXN][MAXN];
14+
15+
// 动态规划方法彻底尝试
16+
// 为了验证
17+
public static String win1(int a, int b, int m) {
18+
if (m >= Math.max(a, b)) {
19+
return a != b ? "先手" : "后手";
20+
}
21+
if (a == b) {
22+
return "后手";
23+
}
24+
if (dp[a][b][m] != null) {
25+
return dp[a][b][m];
26+
}
27+
String ans = "后手";
28+
for (int pick = 1; pick <= Math.min(a, m); pick++) {
29+
if (win1(a - pick, b, m).equals("后手")) {
30+
ans = "先手";
31+
}
32+
if (ans.equals("先手")) {
33+
break;
34+
}
35+
}
36+
for (int pick = 1; pick <= Math.min(b, m); pick++) {
37+
if (win1(a, b - pick, m).equals("后手")) {
38+
ans = "先手";
39+
}
40+
if (ans.equals("先手")) {
41+
break;
42+
}
43+
}
44+
dp[a][b][m] = ans;
45+
return ans;
46+
}
47+
48+
// 正式方法
49+
// 时间复杂度O(1)
50+
public static String win2(int a, int b, int m) {
51+
if (m >= Math.max(a, b)) {
52+
// nim博弈
53+
return a != b ? "先手" : "后手";
54+
}
55+
if (a == b) {
56+
return "后手";
57+
}
58+
// 如果 a != b
59+
// 关注a和b的差值,
60+
// 谁最先遇到差值为0谁输
61+
// 那么这就是巴什博奕
62+
return (Math.max(a, b) - Math.min(a, b)) % (m + 1) != 0 ? "先手" : "后手";
63+
}
64+
65+
public static void main(String[] args) {
66+
System.out.println("测试开始");
67+
for (int a = 0; a < MAXN; a++) {
68+
for (int b = 0; b < MAXN; b++) {
69+
for (int m = 0; m < MAXN; m++) {
70+
String ans1 = win1(a, b, m);
71+
String ans2 = win2(a, b, m);
72+
if (!ans1.equals(ans2)) {
73+
System.out.println("出错了!");
74+
}
75+
}
76+
}
77+
}
78+
System.out.println("测试结束");
79+
}
80+
81+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package class095;
2+
3+
// 斐波那契尼姆博弈(齐肯多夫定理)
4+
// 一共有n枚石子,两位玩家定了如下规则进行游戏:
5+
// 先手后手轮流取石子,先手在第一轮可以取走任意的石子
6+
// 接下来的每一轮当前的玩家最少要取走一个石子,最多取走上一次取的数量的2倍
7+
// 当然,玩家取走的数量必须不大于目前场上剩余的石子数量,双方都以最优策略取石子
8+
// 你也看出来了,根据规律先手一定会获胜,但是先手想知道
9+
// 第一轮自己取走至少几颗石子就可以保证获胜了
10+
// 测试链接 : https://www.luogu.com.cn/problem/P6487
11+
// 请同学们务必参考如下代码中关于输入、输出的处理
12+
// 这是输入输出处理效率很高的写法
13+
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
14+
15+
import java.io.BufferedReader;
16+
import java.io.IOException;
17+
import java.io.InputStreamReader;
18+
import java.io.OutputStreamWriter;
19+
import java.io.PrintWriter;
20+
import java.io.StreamTokenizer;
21+
22+
public class Code06_FibonacciNim {
23+
24+
public static long n, a, b, c, ans;
25+
26+
public static void main(String[] args) throws IOException {
27+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
28+
StreamTokenizer in = new StreamTokenizer(br);
29+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
30+
in.nextToken();
31+
n = (long) in.nval;
32+
ans = -1;
33+
while (n != 1 && n != 2) {
34+
a = 1;
35+
b = 2;
36+
c = 3;
37+
while (c < n) {
38+
a = b;
39+
b = c;
40+
c = a + b;
41+
}
42+
if (n == c) {
43+
ans = c;
44+
break;
45+
} else {
46+
n -= b;
47+
}
48+
}
49+
if (ans != -1) {
50+
out.println(ans);
51+
} else {
52+
out.println(n);
53+
}
54+
out.flush();
55+
out.close();
56+
br.close();
57+
}
58+
59+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package class095;
2+
3+
// 威佐夫博弈
4+
// 有两堆石子,数量任意,可以不同,游戏开始由两个人轮流取石子
5+
// 游戏规定,每次有两种不同的取法
6+
// 1) 在任意的一堆中取走任意多的石子
7+
// 2) 可以在两堆中同时取走相同数量的石子
8+
// 最后把石子全部取完者为胜者
9+
// 现在给出初始的两堆石子的数目,返回先手能不能获胜
10+
// 测试链接 : https://www.luogu.com.cn/problem/P2252
11+
// 请同学们务必参考如下代码中关于输入、输出的处理
12+
// 这是输入输出处理效率很高的写法
13+
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
14+
15+
import java.io.BufferedReader;
16+
import java.io.IOException;
17+
import java.io.InputStreamReader;
18+
import java.io.OutputStreamWriter;
19+
import java.io.PrintWriter;
20+
import java.io.StreamTokenizer;
21+
22+
public class Code07_WythoffGame {
23+
24+
public static double split = (Math.sqrt(5.0) + 1.0) / 2.0;
25+
26+
public static int n, m, min, max, diff;
27+
28+
public static void main(String[] args) throws IOException {
29+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
30+
StreamTokenizer in = new StreamTokenizer(br);
31+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
32+
in.nextToken();
33+
n = (int) in.nval;
34+
in.nextToken();
35+
m = (int) in.nval;
36+
min = Math.min(n, m);
37+
max = Math.max(n, m);
38+
diff = max - min;
39+
if (min == (int) (split * diff)) {
40+
out.println(0);
41+
} else {
42+
out.println(1);
43+
}
44+
out.flush();
45+
out.close();
46+
br.close();
47+
}
48+
49+
}

0 commit comments

Comments
 (0)