题目:
一共有n堆石子,编号1-n,第i堆中有ai个石子,每一次操作A和B可以从任意一堆石子中取出任意数量的石子,至少取一颗,至多取出这一堆剩下的所有石子,两人轮流行动,取光所有石子的一方获胜,A先动手,给定a,假设两人都采取最优策略,谁会获胜
思路:
异或结果时1的,则先拿者胜利。(具体为啥不知道。)
代码
public class _02_Nim游戏 {
public static void main(String[] args) {
int[] arr = {3,4,5};
boolean str = check(arr);
System.out.println(str);
}
static boolean check(int[] arr){
int str = 0;
for (int i = 0; i < arr.length; i++) {
str ^= arr[i];
}
return str!= 0;
}
}
Nim问题升级版
代码如下
package 题解;
import java.util.Scanner;
public class _02_01_Nim问题_下棋 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = scanner.nextInt();
}
deal(arr, n);
}
static void deal(int[] arr, int n){
int res = 0;
if((n % 2) == 1){ //奇数
for (int i = 0; i < n; i+=2) {
//如果是第一个数字,则减去1得到与起点的石子个数。
//如果不是第一个数字,则要两两匹配。
res ^= (i==0)?(arr[0]-1):(arr[i] - arr[i-1] - 1);
System.out.println("i="+i +" res="+ res);
}
} else { //偶数
for (int i = 1; i < n; i+=2) {
//两两匹配即可。
res ^= (arr[i] - arr[i-1] - 1);
System.out.println("i="+i +" res="+ res);
}
}
System.out.println(res);
if(res == 0){
System.out.println("2win");
} else { //只要result不为0,则先手就赢。(坑! 不一定是1)
System.out.println("1win");
}
}
}