PREV-14高僧斗法(尼姆博弈)Java版,可能是全网最详解了
前言
高僧斗法,名字倒是挺有意思,大威天龙…这道题中涉及到了一个我从未接触到的知识,尼姆博弈,对于尼姆博弈,必须要知道奇异局势,以及怎么给对手造成奇异局势,我觉得看百度百科尼姆博弈应该就能明白这些了,知道这些就完全足够解决这道题了。好吧,现在来看看这道题。
问题描述
古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。
节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示N级浮屠)。又有若干小和尚随机地“站”在某个台阶上。最高一级台阶必须站人,其它任意。(如图1所示) ps:这也没图啊,蓝桥杯这个练习系统真狗。
两位参加游戏的法师分别指挥某个小和尚向上走任意多级的台阶,但会被站在高级台阶上的小和尚阻挡,不能越过。两个小和尚也不能站在同一台阶,也不能向低级台阶移动。
两法师轮流发出指令,最后所有小和尚必然会都挤在高段台阶,再也不能向上移动。轮到哪个法师指挥时无法继续移动,则游戏结束,该法师认输。
对于已知的台阶数和小和尚的分布位置,请你计算先发指令的法师该如何决策才能保证胜出。
输入格式
输入数据为一行用空格分开的N个整数,表示小和尚的位置。台阶序号从1算起,所以最后一个小和尚的位置即是台阶的总数。(N<100, 台阶总数<1000)
输出格式
输出为一行用空格分开的两个整数: A B, 表示把A位置的小和尚移动到B位置。若有多个解,输出A值较小的解,若无解则输出-1。
样例输入
1 5 9
样例输出
1 4
样例输入
1 5 8 10
样例输出
1 3
代码
package lanqiao;
import java.util.Arrays;
import java.util.Scanner;
public class PREV_14 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner (System.in);
String s=sc.nextLine();
String c[]=s.split(" ");
int m[]=new int[c.length-1];
for(int i=1;i<c.length;i++){
m[i-1]=Integer.valueOf(c[i])-Integer.valueOf(c[i-1])-1;//得到每堆中的数量
}
//System.out.println(Arrays.toString(m));
int sum=0;
for(int i=0;i<m.length;i=i+2){//i=i+2,对应的是两两配对的数
sum^=m[i];//进行异或操作
}
if(sum==0){//此时已经是奇异局势,我方必输,即无解的情况
//System.out.println(-1);
}
else{//我方能够赢,根据题意,输出A较小的值,所有从最小的和尚开始,尝试进行操作,为对方造成奇异局势
for(int i=0;i<c.length-1;i++){//从最开始的和尚开始
for(int j=1;j+Integer.valueOf(c[i])<Integer.valueOf(c[i+1]);j++){//该和尚能走的所有情况
//j对应的是走的步数,进行遍历
m[i]-=j;//表示走了j步,然后再对剩下的所有数,进行异或操作
if(i!=0){//表示不是第一个和尚了,即就是后面的和尚往后走了
m[i-1]+=j;//那么前面的和尚能走的情况就多了
}
sum=0;
for(int k=0;k<m.length;k=k+2){//对现在的情况进行异或操作
sum^=m[k];
}
if(sum==0){
System.out.println(c[i]+" "+(Integer.valueOf(c[i])+j));
return;
}
//回溯
m[i]+=j;
if(i!=0){
m[i-1]-=j;
}
}
}
}
}
}
总结
代码是借鉴的别人的,我补了注释,网上的其他文章,对一些细节都直接一笔带过了,拿1,5, 8,10这个例子来说,1,5,8,10可分为三堆(3,2,1),但实际上分为两堆即为:(3,1),把1,5看成一对,8,10看成一对,那么5,8为什么不是一对呢,因为假如5,8是一对,5,8之间有2个距离,假设一法师动5,8之间的距离,那么另一法师可以移动距离变大了,也可以移到相同的距离,所以5,8之间的台阶对游戏是没有影响的,这是在总数只有三堆的情况下,如果有n堆,同理,中间的那些不是一对的,都对游戏无关,这也是为什么进行异或操作的循环,每次是加2了,具体如下图,这是随便编的一段样例以上是个人拙见,有错误的地方还望指教。