题目
题目描述
小A在WOW中是个小术士.作为一名术士,不会单刷副本是相当丢脸的.所谓单刷副本就是单挑BOSS了,这么有荣誉感的事小A怎么会不做呢?于是小A来到了厄运之槌开始了单刷.小A看了看,厄运之槌的地图是一个N*M的矩形(N,M<=100),上面遍布了小怪和传送门.例如(1表示有小怪,0表示无小怪,大写字母表示传送门,传送门:例如,走到 B 传送门点将传送到另一个 B 传送点(次数无限,但每次进入传送点只传送过去,不会在传送回来)数据保证每个传送门有且仅有相对应的另一个传送门):
而入口在左上方(1,1),BOSS却躲在右下方(N,M).小A非常急切的想要完成单刷然后去向其他那些战士啊盗贼啊不会单刷的职业炫耀炫耀,所以呢,小A绝不会在小怪身上浪费时间(当然是绕开他们),并且想通过传送门尽快到达BOSS身边.看啊看,想啊想,还是没找出最快的路.终于,灵机一动,想什么啊,编程呗!
[样例说明]
路线如图:
而入口在左上方(1,1),BOSS却躲在右下方(N,M).小A非常急切的想要完成单刷然后去向其他那些战士啊盗贼啊不会单刷的职业炫耀炫耀,所以呢,小A绝不会在小怪身上浪费时间(当然是绕开他们),并且想通过传送门尽快到达BOSS身边.看啊看,想啊想,还是没找出最快的路.终于,灵机一动,想什么啊,编程呗!
[样例说明]
路线如图:
输入
第一行2个数据:n m;
下面n行,每行m个数(入口点和BOSS点无怪和传送门),表示厄运之槌的地图。地图数据之间无空格。每步只能走一格,方向上下左右。左上角为入口点,右下角为出口点.
下面n行,每行m个数(入口点和BOSS点无怪和传送门),表示厄运之槌的地图。地图数据之间无空格。每步只能走一格,方向上下左右。左上角为入口点,右下角为出口点.
输出
一个整数,表示小A最少需要走多少步。如果小A不能走到目标,则输出No Solution.
输入样例复制
3 4
0000
00A0
A000
0000
00A0
A000
输出样例复制
4
说明
对60%的数据,n,m<=20 对100%的数据,n,m<=100
分析
首先是一道搜索题很显然,dfs会爆,我们就用bfs
但这道题的关键是当遇到传送们的时候我们该怎么办呢?
找到另一个传送门
我们可以将传送门的位置进入队列之中
将下一步的值覆盖在传送门上
问题便解决了
代码
1 #include<bits/stdc++.h>
2 #include<cstdio>
3 #include<queue>
4 using namespace std;
5 int n,m;
6 char ss[101];
7 bool flag[101][101];
8 int v[101][101];
9 int a[101][101];
10 int fx[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
11 int x,y;
12 int ans=1e9;
13 void bfs()
14 {
15 memset(v,0x7f,sizeof(v));
16 v[1][1]=0;
17 x=1;
18 y=1;
19 int s1,s2;
20 queue<int> q;
21 q.push(x);
22 q.push(y);
23 while (!q.empty())
24 {
25 s1=q.front();
26 q.pop();
27 s2=q.front();
28 q.pop();
29 int k=v[s1][s2]+1;
30 for (int i=0;i<4;i++)
31 {
32 if (a[s1+fx[i][0]][s2+fx[i][1]]==1&&s1+fx[i][0]<1&&s1+fx[i][0]>n&&s2+fx[i][1]<1&&s2+fx[i][1]>m) continue;
33 if (a[s1+fx[i][0]][s2+fx[i][1]]>9&&flag[s1+fx[i][0]][s2+fx[i][1]]==0)
34 {
35 flag[s1+fx[i][0]][s2+fx[i][1]]=1;
36 for (int ii=1;ii<=n;ii++)
37 for (int jj=1;jj<=m;jj++)
38 if (a[s1+fx[i][0]][s2+fx[i][1]]==a[ii][jj]&&(ii!=s1+fx[i][0]||jj!=s2+fx[i][1]))
39 {
40 v[ii][jj]=min(k,v[ii][jj]);
41 q.push(ii);
42 q.push(jj);
43 }
44 }
45 else if (v[s1+fx[i][0]][s2+fx[i][1]]==2139062143&&a[s1+fx[i][0]][s2+fx[i][1]]==0&&s1+fx[i][0]>=1&&s1+fx[i][0]<=n&&s2+fx[i][1]>=1&&s2+fx[i][1]<=m)
46 {
47 if (s1+fx[i][0]==n&&s2+fx[i][1]==m)
48 ans=min(k,ans);
49 q.push(s1+fx[i][0]);
50 q.push(s2+fx[i][1]);
51 v[s1+fx[i][0]][s2+fx[i][1]]=min(k,v[s1+fx[i][0]][s2+fx[i][1]]);
52 }
53 if (s1+fx[i][0]==n&&s2+fx[i][1]==m)
54 ans=min(k,ans);
55 }
56 }
57 }
58 int main ()
59 {
60 cin>>n>>m;
61 for (int i=1;i<=n;i++)
62 {
63 scanf("%s",ss+1);
64 for (int j=1;j<=m;j++)
65 a[i][j]=ss[j]-48;
66 }
67 bfs();
68 if (ans!=1e9)
69 cout<<ans;
70 else
71 cout<<"No Solution.";
72 }