吴昊品游戏核心算法 Round 16 —— 吴昊教你玩口袋妖怪 第七弹 小茂道馆

 

  小茂啊!让我怎么说你好呢?有时候,永远的对手其实就是永远的朋友吧!任天堂在人物的设定中,小茂总给人一种时而傲娇,时而那么霸气,时而又那么让人讨厌的一种角色。不过,作为每次的口袋妖怪天王战的霸主小茂,总给人一种不可一世的感觉(在口袋妖怪金银的深山中,曾经隐藏着一个比小茂还要强悍的一个角色,没有名字,就是一登场就是一个81级的皮卡丘的那个人)

  这个道馆也比较华丽,给人一种跳舞机的感觉,地板上到处都是箭头,和龙系道馆不一样,这个道馆,我们的方向不是主观可控的了,我们需要遵循着箭头的方向前进。不过,注意到箭头之间还是有缝隙的(也就是存在有空地的地板),我们可以选择一个初始的方向(后面的方向可以说仍然是不可控制的)

  当然,和龙系道馆的场景一样,这里的场景在口袋妖怪中也是随处可见的:

 

  这里是一个场景,注意到黄颜色的正方形区域,该点可以作为一个吸收装置,你如果被转移到那里,你将会被吸收,之后,你会停下来,再进行下一步的走动。

 

  更多的时候,这样的吸收装置是没有的,如图所示,在这种场景中,吸收装置少了许多,更多地,是被一堵墙给代替了。当然,在这里,空地还是存在的,我们这里要做的是,进一步化简!我们消除空地的存在,为什么呢?唯有如此,才能将人的可控制性降低到没有,一个输入才能唯一地对应一个输出,所以,我们将其简化为如下的数学模型:

 

  如图所示,我们的主角从某一个位置(第一行的某一个确定的位置)进入小茂道馆,然后,在一个过程中,达到两种情况中的一个:(1)在某一点被拱出去(2)被吸入一个有限的循环之中(地图被抽象为一个完整的二维数组,其中,完整的含义是不留下任何的空地),N,E,S,W分别代表箭头的指向,是北,东,南还是西。

  Input:第一行三个数字,前面两个代表地图的规模(W*H,最后一个代表我们的主角是从第一行的哪一列开始移动。

  Output:作为一个模拟的问题,我们最终需要知道我们的主角最后怎么了?是陷入了循环的漩涡呢?还是走出了这个漩涡,以至于可以和小茂一决雌雄呢?由于整个地图布满了箭头,所以没有必要考虑AI了,唯一的AI也许就是想想我们的主角小智应该从第一行的哪一列滑行,当然,这一点的话,由于输入和输出都是一一映射的,貌似也没有讨论的价值了。

  Solve:

  Highlights:关于循环的判定是本问题的独特亮点,因为只要是位置上有相同的话,就说明必然存在循环了!该位置就是循环的起始点。考虑到这一步,我们就可以想到利用一个字符数组存储所有的经过,利用strstr函数进行逐一的比对,最重要的还是要找到循环的首元素的下标。

  

 1  #include<stdio.h>
 2  //由于需要字符串函数strstr处理,这里开启头文件
 3 #include<string.h>
 4 int main()
 5 {
 6   //定义地图,以及记录位置的信息:(方向+位置)
 7  char grid[11][12],record[303],record_now[4];
 8  int row,column,start,indicator,a,row_now,column_now,loop,step,step2;
 9  while(scanf("%d%d%d",&row,&column,&start)==3&&(row!=0||column!=0||start!=0))
10  {
11   //数组清空
12   strcpy(record,"");
13   //记录循环节的大小
14   step=0;
15   //读入一个地图
16   for(a=0;a<row;a++)
17    scanf("%s",grid[a]);
18   //第一格无所谓,无论标注什么都是可以的
19   record_now[0]=48;
20   record_now[1]=48+start-1;
21   record_now[2]='E';
22   record_now[3]='\0';
23   //记录数组的下标
24   indicator=0;
25   row_now=0;
26   loop=0;
27   column_now=start-1;
28   //越界的话,就退出
29   while(row_now>=0&&row_now<=row-1&&column_now>=0&&column_now<=column-1)
30   {
31   //如果没有出现循环的话,分别对以下四种情况进行处理
32    if(strstr(record,record_now)==NULL)
33    {
34     strcpy(&record[indicator],record_now);
35     indicator+=3;
36     step++;
37     if(grid[row_now][column_now]=='N')
38     {
39      row_now--;
40      record_now[0]--;
41     }
42     else if(grid[row_now][column_now]=='S')
43     {
44      row_now++;
45      record_now[0]++;
46     }
47     else if(grid[row_now][column_now]=='E')
48     {
49      column_now++;
50      record_now[1]++;
51     }
52     else
53     {
54      column_now--;
55      record_now[1]--;
56     }
57    }
58   //如果循环的话,确定循环的首元素的位置,将loop置1
59    else
60    {
61     step2=(indicator-(strstr(record,record_now)-record))/3;
62     loop=1;
63     break;
64    }
65   }
66   if(loop)
67    printf("%d step(s) before a loop of %d step(s)\n",step-step2,step2);
68   else
69    printf("%d step(s) to exit\n",step);
70  
71  }
72  return 0;
73 }

posted on 2013-04-01 11:39  吴昊系列  阅读(1443)  评论(3编辑  收藏  举报

导航