C++-旅游 解题思路
【Horn Studio】编程专栏: 旅游 解题思路
题目
题目描述
在一个大小为n∗mn∗m的方格地图mp[][]mp[][]上,初始时你在方格(1,1)(1,1)位置。有kk个旅游景点你想去玩。
地图中标记为..的方格可以行走,标记为##的方格有障碍物不能经过,标记为数字的方格表示景点的编号。
每秒钟你可以朝上,下,左或右移动一格位置,问最少花多少时间走遍kk个景点。
如果无法走遍kk个景点则输出−1−1。保证起点的方格没有障碍物。
地图中标记为..的方格可以行走,标记为##的方格有障碍物不能经过,标记为数字的方格表示景点的编号。
每秒钟你可以朝上,下,左或右移动一格位置,问最少花多少时间走遍kk个景点。
如果无法走遍kk个景点则输出−1−1。保证起点的方格没有障碍物。
输入
第一行三个正整数表示n,m,kn,m,k。
接下来nn行,每行一个长度为mm的字符串表示地图mp[][]mp[][]。
1≤n,m≤20,1≤k≤91≤n,m≤20,1≤k≤9。
接下来nn行,每行一个长度为mm的字符串表示地图mp[][]mp[][]。
1≤n,m≤20,1≤k≤91≤n,m≤20,1≤k≤9。
输出
输出一个整数表示答案。
样例输入 复制
5 7 3
.......
....1..
..2#.3.
.......
.......
样例输出 复制
9
提示
样例:先去2,再去1,再去3。
5 8 3
....#..1
........
##...###
........
.2..#..3
25
先去2,再去3,再去1。
3 6 1
..#..1
..#...
..####
-1
思路
首先画一下图理解一下:
(有点菜,理解万岁!)
( 这样来说的话是出不去的)
同样是字符,使用现场转换后需要容易得多!就像这样:
1 char ch; 2 cin >> ch; 3 if (i == 1 && j == 1){ 4 mp[i][j] = 0; 5 else { 6 if (ch == '.') { 7 mp[i][j] = -1; 8 } else if (ch == '#') { 9 mp[i][j] = -2; 10 } else { 11 mp[i][j] = ch - '0'; 12 } 13 }
接下来的事情很简单了。
将出生点(0,0)设置为景点0,而bfs就是判断从这里到那里需要的步数,就很Easy了!另外还需要一个dfs来计算Steps,更为简单!
接下来就是实现代码操作了,代码不多,也就93行而已。
代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, m, k; 4 int mp[25][25]; 5 6 struct qnode { 7 int x, y; 8 }; 9 10 int tx[] = {0, -1, 0, 1}; 11 12 int ty[] = {1, 0, -1, 0}; 13 queue<qnode> que; 14 int dis[25][25], cost[25][25], vis[25][25]; 15 16 void bfs(int sx, int sy) 17 { 18 for (int i = 1; i <= n; i++) { 19 for (int j = 1; j <= m; j++) { 20 dis[i][j] = 1e9; 21 } 22 } 23 memset(vis, 0, sizeof(vis)); 24 que.push({sx, sy}); 25 vis[sx][sy] = 1; 26 dis[sx][sy] = 0; 27 while (que.size()) { 28 qnode tmp = que.front(); 29 que.pop(); 30 int x = tmp.x; 31 int y = tmp.y; 32 if (mp[x][y] >= 0 && mp[x][y] <= 9) { 33 cost[mp[sx][sy]][mp[x][y]] = cost[mp[x][y]][mp[sx][sy]] = dis[x][y]; 34 } 35 for (int i = 0; i < 4; i++) { 36 int nx = x + tx[i]; 37 int ny = y + ty[i]; 38 if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && mp[nx][ny] != -2 && vis[nx][ny] == 0) { 39 dis[nx][ny] = dis[x][y] + 1; 40 vis[nx][ny] = 1; 41 que.push({nx, ny}); 42 } 43 } 44 } 45 } 46 int used[20], ans = 1e9; 47 48 void dfs(int u, int val, int cnt) 49 { 50 used[u] = 1; 51 if (cnt == k) { 52 ans = min(ans, val); 53 } 54 for (int i = 1; i <= k; i++) { 55 if (used[i] == 0) { 56 dfs(i, val + cost[u][i], cnt + 1); 57 } 58 } 59 used[u] = 0; 60 } 61 62 int main() 63 { 64 cin >> n >> m >> k; 65 for (int i = 1; i <= n; i++) { 66 for (int j = 1; j <= m; j++) { 67 char ch; 68 cin >> ch; 69 if (i == 1 && j == 1) 70 mp[i][j] = 0; 71 else { 72 if (ch == '.') { 73 mp[i][j] = -1; 74 } else if (ch == '#') { 75 mp[i][j] = -2; 76 } else { 77 mp[i][j] = ch - '0'; 78 } 79 } 80 } 81 } 82 for (int i = 1; i <= n; i++) { 83 for (int j = 1; j <= m; j++) { 84 if (mp[i][j] >= 0 && mp[i][j] <= 9) { 85 bfs(i, j); 86 } 87 } 88 } 89 dfs(0, 0, 0); 90 if(ans==0) cout<<-1; 91 else cout << ans; 92 return 0; 93 }
彩蛋
:你瞧瞧这附近哪有彩蛋那,这都是大棚里挑的……