高僧斗法

问题描述

  古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。
  节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示N级浮屠)。又有若干小和尚随机地“站”在某个台阶上。最高一级台阶必须站人,其它任意。(如图1所示)
  两位参加游戏的法师分别指挥某个小和尚向上走任意多级的台阶,但会被站在高级台阶上的小和尚阻挡,不能越过。两个小和尚也不能站在同一台阶,也不能向低级台阶移动。
  两法师轮流发出指令,最后所有小和尚必然会都挤在高段台阶,再也不能向上移动。轮到哪个法师指挥时无法继续移动,则游戏结束,该法师认输。
  对于已知的台阶数和小和尚的分布位置,请你计算先发指令的法师该如何决策才能保证胜出。
输入格式
  输入数据为一行用空格分开的N个整数,表示小和尚的位置。台阶序号从1算起,所以最后一个小和尚的位置即是台阶的总数。(N<100, 台阶总数<1000)
输出格式
  输出为一行用空格分开的两个整数: A B, 表示把A位置的小和尚移动到B位置。若有多个解,输出A值较小的解,若无解则输出-1。
样例输入
1 5 9
样例输出
1 4
样例输入
1 5 8 10
样例输出
1 3

Algorithm

这个题目看了很久想不到方法,看了下提示,要用到博弈论的知识,而且还是Nim游戏,因此特意学习了Nim游戏:传送门~

我觉得我不能讲的比他还要好了^_^,感谢一下博主。

这个题目我们转化一下,就成了Nim游戏。

将小和尚两两分组,就像这样:

值得注意的一点是,区间间隔可能会增加,也可能会减少。


 AC

 1 /*
 2 * 博弈论 
 3 * 尼姆博弈 - Nim 
 4 * 再此警告一下一下自己啊, 千万不要用 new 来分配内存
 5 * 不然怎么错的都不知道......
 6 * 内存泄漏会导致返回值不一定为 0 
 7 * 但是比赛必须为 0  
 8 */
 9 #include<iostream>
10 #include<string>
11 #include<sstream>
12 #include<cstdio>
13  
14 using namespace std;
15 
16 void fun(int *a, int n)
17 {
18     int x[109] = {0};
19     int k = 0, mx = 0, loc = 0;
20     for(int i=1;i<n;i+=2)
21         x[k++] = a[i] - a[i-1] - 1;
22     int t = 0;
23     for(int i=0;i<k;i++){
24         t ^= x[i];
25     }
26     if(!t){    // 平衡态先手必输 
27         cout<<-1<<'\n';
28         return;
29     }
30     int temp = 0;
31     for(int j=0;j<n;j++){
32         for(int k=a[j]+1;k<a[j+1];k++){
33             if(j&1){    // 增大间距 
34                 if(!(t^x[j>>1]^(k-a[j-1]-1))){
35                     printf("%d %d\n", a[j], k);
36                     return;
37                 }
38             }
39             else{        // 缩小间距 
40                 if(!(t^x[j>>1]^(a[j+1]-k-1))){
41                     printf("%d %d\n", a[j], k);
42                     return;
43                 }
44             } 
45         }
46     }     
47     /*
48     for(int j=0;j<k;j++)
49         cout<<x[j]<<' ';
50     */
51 }
52 
53 int main()
54 {
55     string s;
56     while(getline(cin, s))
57     {    
58         stringstream ss(s);
59         int x = 0, i = 0;
60         int a[109] = {0};
61         while(ss>>a[i++]);
62         ss.clear();
63         fun(a, i-1);
64         /*
65         for(int j=0;j<i-1;j++)
66             cout<<a[j]<<' ';
67         cout<<'\n';
68         */
69     }
70     
71     return 0;
72 }
View Code

 

2019-02-26

22:04:08

posted @ 2019-02-26 22:06  maybeTang  阅读(335)  评论(0编辑  收藏  举报