题目
题目描述
小Y
在OIER
中是个菜鸟,作为一名菜鸟,如果能挑战K神是个有荣誉感的事小Y
怎么会放过呢?于是小Y
来到了OIER
们的活动场所——Playground
开始了挑战赛小Y
看了看,Playground
的地图是一个$N*M$的矩形($N,M\leqslant 100$),里面遍布了障碍和一些传送带
例如,1
表示该位置有障碍,0
表示无障碍,大写字母表示传送带
传送带:例如,走到B
传送带,将传送到另一个B
传送带(次数无限,但每次进入传送带只会传送过去,不会再传送回来)
| 入口 | 0 | 0 | 0 |
|—|—|—|—|
| 0 | 0 | A | 0 |
| A | 0 | 0 | K神
|
输入格式
第一行$2$个数据$n,m$
下面$n$行,每行$m$个数(入口点、K神
、障碍、无障碍的空地和传送带),表示Playground
的地图。地图数据之间无空格
每步只能走一格,方向为上下左右,左上角为入口点,右下角为出口点(K神
)
输出格式
一个整数,表示小Y
最少需要走多少步
如果小Y
不能走到目标,则输出No Solution.
样例
样例输入
1 | 3 4 |
样例输出
1 | 4 |
数据范围与提示
样例说明
路线如图:
数据范围
对$60\%$的数据:$n,m\leqslant 20$
对$100\%$的数据:$n,m\leqslant 100$
题解
基本的搜索题……
就是一个宽搜,记录下所有的传送带的坐标,遇到传送带就直接传送就好了
没有什么好说的了,附上代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
struct ppap
{
int x,y,s;
}q[10010];
int n,m,l,r,dx[5]={-1,0,1,0},dy[5]={0,-1,0,1},c1[30][5],c2[30][5],v[110][110];
char map[110][110];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
scanf(" %c",&map[i][j]);
if(map[i][j]>='A'&&map[i][j]<='Z'){
if(!c1[map[i][j]-'A'+1][1]) c1[map[i][j]-'A'+1][1]=i,c1[map[i][j]-'A'+1][2]=j;
else c2[map[i][j]-'A'+1][1]=i,c2[map[i][j]-'A'+1][2]=j;
}
}
r=q[1].x=q[1].y=v[1][1]=1;
while(l<r){
int x=q[++l].x,y=q[l].y;
if(x==n&&y==m){printf("%d",q[l].s);return 0;}
if(map[x][y]>='A'&&map[x][y]<='Z'){
int temp=map[x][y]-'A'+1;
if(c1[temp][1]==x&&c1[temp][2]==y) x=c2[temp][1],y=c2[temp][2];
else x=c1[temp][1],y=c1[temp][2];
}
for(int i=0;i<4;i++){
int X=x+dx[i],Y=y+dy[i];
if(X>0&&X<=n&&Y>0&&Y<=m&&(!v[X][Y])&&map[X][Y]!='1') q[++r].x=X,q[r].y=Y,q[r].s=q[l].s+1,v[X][Y]=1;
}
}
printf("No Solution.");
}