题目:有几堆石子,两个人从中取,一次可以取多个(至少一个),当某个人取的时候石子为0,则这个人输,问在自己有必赢策略情况下,第一步可以取哪些堆的石子,使得对方为必输状态?
首先要知道NIM博弈问题的结论;
对于一个局面,当且仅当A[1] xor A[2] xor ... xor A[N] = 0时,该局面为P局面,也就是必输局面
当不等于0的时候,存在必赢策略
思路:
首先判断自己是否为必输局面,为必输局面则输出0
有赢得策略的话,分析第一步怎么走才能使得对方为必输状态,详细的解释在代码注释中
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int count = 0;
int n;
while((n = input.nextInt())!=0){
int[] arr = new int[n];
for (int i = 0; i < arr.length; i++) {
arr[i] = input.nextInt();
}
int remain = 0;
for (int i = 0; i < arr.length; i++) {
remain = remain^arr[i];//根据公式推算出有没有必胜的策略
}
//如果没有则输出0
if (remain == 0) {
System.out.println(0);
}else {//存在必胜策略,但不一定胜利,分析出能胜利的第一步方案
for (int i = 0; i < arr.length; i++) {
/**
* 原本remain = arr[1]^arr[2]----
* 现在remain^arr[i]意思是假设不存在这个堆,剩余的堆能推测出的状态假设为s个石子,
* 只要s比当前堆小,我们就可以在第一步的时候取出一定石子.让当前堆变成s个石子,
* 这样的话自己走完第一步,对于对方来说,就是必输状态
*/
if ((remain^arr[i]) < arr[i]) {
count++;
}
}
System.out.println(count);
}
}
}
}
时间: 2024-09-15 21:18:52