小茂啊!让我怎么说你好呢?有时候,永远的对手其实就是永远的朋友吧!任天堂在人物的设定中,小茂总给人一种时而傲娇,时而那么霸气,时而又那么让人讨厌的一种角色。不过,作为每次的口袋妖怪天王战的霸主小茂,总给人一种不可一世的感觉(在口袋妖怪金银的深山中,曾经隐藏着一个比小茂还要强悍的一个角色,没有名字,就是一登场就是一个81级的皮卡丘的那个人)
这个道馆也比较华丽,给人一种跳舞机的感觉,地板上到处都是箭头,和龙系道馆不一样,这个道馆,我们的方向不是主观可控的了,我们需要遵循着箭头的方向前进。不过,注意到箭头之间还是有缝隙的(也就是存在有空地的地板),我们可以选择一个初始的方向(后面的方向可以说仍然是不可控制的)
当然,和龙系道馆的场景一样,这里的场景在口袋妖怪中也是随处可见的:
这里是一个场景,注意到黄颜色的正方形区域,该点可以作为一个吸收装置,你如果被转移到那里,你将会被吸收,之后,你会停下来,再进行下一步的走动。
更多的时候,这样的吸收装置是没有的,如图所示,在这种场景中,吸收装置少了许多,更多地,是被一堵墙给代替了。当然,在这里,空地还是存在的,我们这里要做的是,进一步化简!我们消除空地的存在,为什么呢?唯有如此,才能将人的可控制性降低到没有,一个输入才能唯一地对应一个输出,所以,我们将其简化为如下的数学模型:
如图所示,我们的主角从某一个位置(第一行的某一个确定的位置)进入“小茂道馆”,然后,在一个过程中,达到两种情况中的一个:(1)在某一点被拱出去(2)被吸入一个有限的循环之中(地图被抽象为一个完整的二维数组,其中,完整的含义是不留下任何的空地),N,E,S,W分别代表箭头的指向,是北,东,南还是西。
Input:第一行三个数字,前面两个代表地图的规模(W*H),最后一个代表我们的主角是从第一行的哪一列开始移动。
Output:作为一个模拟的问题,我们最终需要知道我们的主角最后怎么了?是陷入了循环的漩涡呢?还是走出了这个漩涡,以至于可以和小茂一决雌雄呢?由于整个地图布满了箭头,所以没有必要考虑AI了,唯一的AI也许就是想想我们的主角小智应该从第一行的哪一列滑行,当然,这一点的话,由于输入和输出都是一一映射的,貌似也没有讨论的价值了。
Solve:
Highlights:关于循环的判定是本问题的独特亮点,因为只要是位置上有相同的话,就说明必然存在循环了!该位置就是循环的起始点。考虑到这一步,我们就可以想到利用一个字符数组存储所有的经过,利用strstr函数进行逐一的比对,最重要的还是要找到循环的首元素的下标。
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 }