Bash游戏

Bash游戏

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1066

有一堆石子共有N个。A B两个人轮流拿,A先拿。每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜。
假设A B都非常聪明,拿石子的过程中不会出现失误。给出N和K,问最后谁能赢得比赛。

例如N = 3,K = 2。无论A如何拿,B都可以拿到最后1颗石子。

Input

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行2个数N,K。中间用空格分隔。(1 <= N,K <= 10^9)

Output

共T行,如果A获胜输出A,如果B获胜输出B。

Input示例

4
3 2
4 2
7 3
8 3

Output示例

B
A
A
B

分析:

N % (K + 1) == 0 时,先手必输。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();
int T = (int) in.nval;
int[] N = new int[T], K = new int[T];
for (int i = 0; i < T; i++) {
in.nextToken();
N[i] = (int) in.nval;
in.nextToken();
K[i] = (int) in.nval;
}

for (int i = 0; i < T; i++) {
if (N[i] % (K[i] + 1) == 0) {
out.println("B");
} else {
out.println("A");
}
}
out.flush();
}
}

Bash游戏 V2

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1067

有一堆石子共有N个。A B两个人轮流拿,A先拿。每次只能拿1,3,4颗,拿到最后1颗石子的人获胜。
假设A B都非常聪明,拿石子的过程中不会出现失误。给出N,问最后谁能赢得比赛。

例如N = 2。A只能拿1颗,所以B可以拿到最后1颗石子。

Input

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行1个数N。(1 <= N <= 10^9)

Output

共T行,如果A获胜输出A,如果B获胜输出B。

Input示例

3
2
3
4

Output示例

B
A
A

分析:

想不出来的话,可以通过 SG 函数打表发现规律:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.Arrays;

public class Main {
static int MAXN = 105;
static int N = 3;
static int[] f = { 1, 3, 4 };
static boolean[] isVisit = new boolean[MAXN];
static int[] SG = new int[MAXN];

public static void main(String[] args) {
getSG(100);
}

static void getSG(int n) {
for (int i = 1; i < n; i++) {
Arrays.fill(isVisit, false);
for (int j = 0; j < N && f[j] <= i; j++) {
isVisit[SG[i - f[j]]] = true;
}
for (int j = 0;; j++) {
if (!isVisit[j]) {
SG[i] = j;
break;
}
}
System.out.println(i + " " + SG[i]);
}
}
}

可以发现只有 mod 7 = 0、mod 7 = 2 必败。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();
int T = (int) in.nval;
int[] a = new int[T];
for (int i = 0; i < T; i++) {
in.nextToken();
a[i] = (int) in.nval;
}

for (int i = 0; i < T; i++) {
out.println(a[i] % 7 == 0 || a[i] % 7 == 2 ? "B" : "A");
}
out.flush();
}
}

Bash游戏 V3

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1068

有一堆石子共有N个。A B两个人轮流拿,A先拿。每次拿的数量只能是2的正整数次幂,比如(1,2,4,8,16….),拿到最后1颗石子的人获胜。
假设A B都非常聪明,拿石子的过程中不会出现失误。给出N,问最后谁能赢得比赛。

例如N = 3。A只能拿1颗或2颗,所以B可以拿到最后1颗石子。(输入的N可能为大数)

Input

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 1000)
第2 - T + 1行:每行1个数N。(1 <= N <= 10^1000)

Output

共T行,如果A获胜输出A,如果B获胜输出B。

Input示例

3
2
3
4

Output示例

A
B
A

分析:

同样可以通过 SG 函数打表发现规律:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.util.Arrays;

public class Main {
static int MAXN = 105;
static int N = 20;
static int[] f = new int[N];
static boolean[] isVisit = new boolean[MAXN];
static int[] SG = new int[MAXN];

public static void main(String[] args) throws IOException {
for (int i = 0; i < N; i++) {
f[i] = (int) Math.pow(2, i);
}
getSG(100);
}

static void getSG(int n) {
for (int i = 1; i < n; i++) {
Arrays.fill(isVisit, false);
for (int j = 0; j < N && f[j] <= i; j++) {
isVisit[SG[i - f[j]]] = true;
}
for (int j = 0;; j++) {
if (!isVisit[j]) {
SG[i] = j;
break;
}
}
System.out.println(i + " " + SG[i]);
}
}
}

mod 3 = 0 必败。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;

public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
int T = Integer.parseInt(in.readLine());
BigInteger three = BigInteger.valueOf(3);
for (int i = 0; i < T; i++) {
BigInteger N = new BigInteger(in.readLine());
out.println(N.mod(three).intValue() == 0 ? "B" : "A");
}
out.flush();
}
}

Bash游戏 V4

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1070

有一堆石子共有N个。A B两个人轮流拿,A先拿。每次拿的数量最少1个,最多不超过对手上一次拿的数量的2倍(A第1次拿时要求不能全拿走)。拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N,问最后谁能赢得比赛。

例如N = 3。A只能拿1颗或2颗,所以B可以拿到最后1颗石子。

Input

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 1000)
第2 - T + 1行:每行1个数N。(1 <= N <= 10^9)

Output

共T行,如果A获胜输出A,如果B获胜输出B。

Input示例

3
2
3
4

Output示例

B
B
A

分析:

当石头数为斐波那契数时,必败。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
static int N = 50;
static int[] f = new int[N];

public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
getFibonacci();
in.nextToken();
int T = (int) in.nval;
for (int i = 0; i < T; i++) {
in.nextToken();
int n = (int) in.nval;
if (isFibonacci(n)) {
out.println("B");
} else {
out.println("A");
}
}
out.flush();
}

static void getFibonacci() {
f[0] = f[1] = 1;
for (int i = 2; i < N; i++) {
f[i] = f[i - 1] + f[i - 2];
}
}

static boolean isFibonacci(int n) {
for (int j = 1; j < N; j++) {
if (n == f[j]) {
return true;
}
}
return false;
}
}
Author

Zoctan

Posted on

2018-03-14

Updated on

2023-03-14

Licensed under