题意:题目给定一个n*m的地图,地图有一个起点标记为'@',还有'#'表示不能够走的,'.'表示可以走。给定k个点,问从起点开始把这k个点走过去的最小步数。
思路:题目k的最大为4,那么我们就可以直接暴力k个点的走的顺序,然后利用bfs即可
代码:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int MAXN = 110; int n , m , k; int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}}; char mat[MAXN][MAXN]; struct Node{ int x; int y; int step; }; Node start; Node node[5]; bool isOk(int x , int y){ if(x >= 1 && x <= n && y >= 1 && y <= m) return true; return false; } int bfs(Node begin , Node end){ queue<Node>q; bool vis[MAXN][MAXN]; memset(vis , false , sizeof(vis)); begin.step = 0; q.push(begin); vis[begin.x][begin.y] = true; while(!q.empty()){ Node tmp = q.front(); q.pop(); if(tmp.x == end.x && tmp.y == end.y) return tmp.step; for(int i = 0 ; i < 4 ; i++){ int x = tmp.x+dir[i][0]; int y = tmp.y+dir[i][1]; if(isOk(x , y) && !vis[x][y] && mat[x][y] == '.'){ q.push((Node){x , y , tmp.step+1}); vis[x][y] = true; } } } return INF; } void solve(){ int tmp[5]; int ans = INF; for(int i = 0 ; i < k ; i++) tmp[i] = i+1; int step = bfs(start , node[tmp[0]]); for(int i = 1 ; i < k ; i++) step += bfs(node[tmp[i-1]] , node[tmp[i]]); ans = min(ans , step); while(next_permutation(tmp , tmp+k)){ int step = bfs(start , node[tmp[0]]); for(int i = 1 ; i < k ; i++) step += bfs(node[tmp[i-1]] , node[tmp[i]]); ans = min(ans , step); } printf("%d\n" , ans == INF ? -1 : ans); } int main(){ while(scanf("%d%d%*c" , &n , &m) && n+m){ for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= m ; j++){ scanf("%c" , &mat[i][j]); if(mat[i][j] == '@'){ start = (Node){i , j , 0}; } } getchar(); } scanf("%d" , &k); for(int i = 1 ; i <= k ; i++) scanf("%d%d" , &node[i].x , &node[i].y); solve(); } return 0; }