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