旅游

题目

题目描述

在一个大小为n∗m的方格地图mp[][]上,初始时你在方格(1,1)位置。有k个旅游景点你想去玩。
地图中标记为.的方格可以行走,标记为#的方格有障碍物不能经过,标记为数字的方格表示景点的编号。
每秒钟你可以朝上,下,左或右移动一格位置,问最少花多少时间走遍k个景点。
如果无法走遍k个景点则输出−1。保证起点的方格没有障碍物。

输入

第一行三个正整数表示n,m,k。
接下来n行,每行一个长度为m的字符串表示地图mp[][]。
1≤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就是判断从这里到那里需要的步数,另外还需要一个dfs来计算Steps.

代码

#include <bits/stdc++.h>
using namespace std;
int n, m, k;
int mp[25][25];
struct qnode {
    int x, y;
};
int tx[] = {0, -1, 0, 1}; 
int ty[] = {1, 0, -1, 0};
queue<qnode> que;
int dis[25][25], cost[25][25], vis[25][25]; 
void bfs(int sx, int sy) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            dis[i][j] = 1e9;
        }
    }
    memset(vis, 0, sizeof(vis));
    que.push({sx, sy});
    vis[sx][sy] = 1;
    dis[sx][sy] = 0;
    while (que.size()) {
        qnode tmp = que.front();
        que.pop();
        int x = tmp.x;
        int y = tmp.y;
        if (mp[x][y] >= 0 && mp[x][y] <= 9) {
            cost[mp[sx][sy]][mp[x][y]] = cost[mp[x][y]][mp[sx][sy]] = dis[x][y];
        }
        for (int i = 0; i < 4; i++) {
            int nx = x + tx[i];
            int ny = y + ty[i];
            if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && mp[nx][ny] != -2 && vis[nx][ny] == 0) {
                dis[nx][ny] = dis[x][y] + 1;
                vis[nx][ny] = 1;
                que.push({nx, ny});
            }
        }
    }
}
int used[20], ans = 1e9; 
void dfs(int u, int val, int cnt) {
    used[u] = 1;
    if (cnt == k) {
        ans = min(ans, val);
}
    for (int i = 1; i <= k; i++) {
        if (used[i] == 0) {
            dfs(i, val + cost[u][i], cnt + 1);
        }
    }
    used[u] = 0;
} 
int main(){
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            char ch;
            cin >> ch;
            if (i == 1 && j == 1)
                mp[i][j] = 0;
            else {
                if (ch == '.') {
                    mp[i][j] = -1;
                } else if (ch == '#') {
                    mp[i][j] = -2;
                } else {
                    mp[i][j] = ch - '0';
                }
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (mp[i][j] >= 0 && mp[i][j] <= 9) {
                bfs(i, j);
            }
        }
    }
    dfs(0, 0, 0);
    if(ans==0) cout<<-1;
    else cout << ans;
    return 0;
}

小编蒟蒻一个,有什么问题请大佬不惜赐教Orz

posted @ 2022-04-15 20:13  骆美辰  阅读(21)  评论(0编辑  收藏  举报
lock: { enable: true, background: 'https://img1.baidu.com/it/u=2788089125,168843488&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1690563600&t=35fa4326e773b3fbf83562ad746b7cd2',//锁屏背景 strings: [ 'Every win named never give up 每一份胜利都叫不放弃',//签名 ], },