关于博弈问题
eg1、盒子中有n个球,A、B两人轮流取球,规定从盒子中取球的数目是1、3、7或8个,A先取球,然后双方交替取球,直到取完,被迫拿到最后一个球的一方失败。问:在双方都不判断失误的情况下,对于特定的初始球数,A是否能赢?
输入:先输入一个整数n,表示接下来的n个整数,每个占一行,表示初始球数。
输出:输出0表示A失败,输出1表示A胜利。
思路:f(局面x)------>胜负?
针对边界条件的处理
f(对A的所有可能取法){
试着取一种情况----->会产生局面y;
胜负 t = f(y);
if(t == 负) return 胜;
}
return false;
import java.util.Scanner;
public class A{
public static boolean f(int n){
if(n>=1 && f(n-1)==false) return true;
if(n>=3 && f(n-3)==false) return true;
if(n>=7 && f(n-7)==false) return true;
if(n>=8 && f(n-8)==false) return true;
return false;
}
public static void main(String [] args){
Scanner cin = new Scanner(System.in);
int N = cin.nextInt();
for(int i = 0;i<N;i++){
int s[] = new int[N];
int s[i] = cin.nextInt();
System.out.println(f(s[i]));
}
}
}
eg2、高僧斗法
思想:将高僧斗法问题转换成尼姆问题,把小和尚位置间的空隙看作是尼姆堆,偶数的话是两两组合,奇数的话就在最高阶补一个假的和尚,又变成了偶数。小组是跟随操作,不改变尼姆堆的值。
把整数转换成二进制数,观察纵排的1的个数是否为偶数。
import java.util.Scanner;
public class heshang {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(System.in);
String[] ss = cin.nextLine().split(" ");
int[] x = new int[ss.length];
for(int i = 0;i<ss.length;i++) {
x[i] = Integer.parseInt(ss[i]);
}
test(x);
}
public static boolean f(int[] x) {
String[] y = new String[x.length];
int m = 0;
for(int i = 0;i<x.length/2;i++) {
y[i] = Integer.toBinaryString(x[i*2+1]-x[i*2]-1);
if(y[i].length()>m) {
m = y[i].length();
}
}
for(int i = 0;i<m;i++) {
boolean tag = true;
for(int j = 0;j<y.length;j++) {
int k = y[j].length()-(m-i);
if(k>0 && y[i].charAt(k)=='1') {
tag = !tag;
}
}
if(tag == false) return false;
}
return true;
}
public static void test(int[]x) {
for(int i = 0;i<x.length-1;i++) {
for(int k = x[i]+1;k<x[i+1];k++) {
int old = x[i];
x[i] = k;
try {
if(f(x)) {
System.out.println(old+" "+k);
}
}
finally{
x[i] = old;
}
}
}
}
}
和上一遍的最后那段代码一样,在我的电脑上还是不能运行,望见谅!以后再改进吧!