蓝桥杯 高僧斗法

古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。
节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示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 }

 

posted @ 2019-02-14 19:16  Frontierone  阅读(382)  评论(0编辑  收藏  举报