蓝桥杯 高僧斗法
古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。
节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示N级浮屠)。又有若干小和尚随机地“站”在某个台阶上。最高一级台阶必须站人,其它任意。(如图1所示)
两位参加游戏的法师分别指挥某个小和尚向上走任意多级的台阶,但会被站在高级台阶上的小和尚阻挡,不能越过。两个小和尚也不能站在同一台阶,也不能向低级台阶移动。
两法师轮流发出指令,最后所有小和尚必然会都挤在高段台阶,再也不能向上移动。轮到哪个法师指挥时无法继续移动,则游戏结束,该法师认输。
对于已知的台阶数和小和尚的分布位置,请你计算先发指令的法师该如何决策才能保证胜出。
输入数据为一行用空格分开的N个整数,表示小和尚的位置。台阶序号从1算起,所以最后一个小和尚的位置即是台阶的总数。(N<100, 台阶总数<1000)
输出为一行用空格分开的两个整数: A B, 表示把A位置的小和尚移动到B位置。若有多个解,输出A值较小的解,若无解则输出-1。
博弈介绍:https://www.cnblogs.com/ACMerszl/p/10371521.html
尼姆博弈变形。把小和尚两两一组,两两之间的空位就是石子,因为第2个和第3个之间的位置是无用的。
处理出来之后异或即可。
第一步如何走,就枚举第i个可以走的位置,然后再异或。满足输出,不满足继续。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 char buf[250]; 5 int a[110]; 6 7 int fun(int n) { 8 int sum=0; 9 for(int i=0;i<n-1;i+=2) sum^=a[i+1]-a[i]-1; 10 return sum==0; //必胜 11 } 12 13 int main() { 14 while(gets(buf)) { 15 int v,cnt=0; 16 char *p=strtok(buf," "); 17 while(p) { 18 sscanf(p,"%d",&v); 19 a[cnt++]=v; 20 p=strtok(NULL," "); 21 } 22 if(cnt&1) { 23 a[cnt]=a[cnt-1]+1; 24 cnt++; 25 } 26 //for(int i=0;i<cnt;i++) printf("%d ",a[i]); 27 bool flag=false; 28 for(int i=0;i<cnt-1;i++) { 29 for(int j=1;a[i]+j<a[i+1];j++) { 30 int st=a[i]; 31 a[i]+=j; 32 if(fun(cnt)) { 33 flag=true; 34 printf("%d %d\n",st,st+j); 35 break; 36 } 37 a[i]=st; 38 } 39 if(flag) break; 40 } 41 if(!flag) puts("-1"); 42 } 43 }
埋骨何须桑梓地,人生无处不青山