蒜头君得到一张藏宝图。藏宝图是一个 10×1010 \times 1010×10 的方格地图,图上一共有 101010 个宝藏。有些方格地形太凶险,不能进入。
整个图只有一个地方可以出入,即是入口也是出口。蒜头君是一个贪心的人,他规划要获得所有宝藏以后才从出口离开。
藏宝图上从一个方格到相邻的上下左右的方格需要
111 天的时间,蒜头君从入口出发,找到所有宝藏以后,回到出口,最少需要多少天。
// 思路 : 以每个宝藏为点建图,预先处理每个点间的距离然后全排列路径最后计算结果
#include <stdlib.h> #include <cstdio> #include <algorithm> #include <string> #include <string.h> #include <iostream> #include <cmath> #include <queue> #include <vector> #define N 1000 using namespace std; char mp[50][50]; struct node{ int x,y; int t; }; int Next[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; int mk[50][50]; int dis[50][50]; void bfs(int x,int y,int s) { node tmp; tmp.t = 0; tmp.x = x; tmp.y = y; queue <node> q; q.push(tmp); memset(mk,0,sizeof(mk)); mk[x][y] = 1; while(q.size()) { tmp=q.front(); q.pop(); for(int i = 0;i < 4; i++) { x = tmp.x + Next[i][0]; y = tmp.y + Next[i][1]; if(x < 1 || y < 1 || x > 10 || y > 10) continue; if(mk[x][y]) continue; if(mp[x][y] == 'x') continue; mk[x][y] = 1; if(mp[x][y] != 'x' && mp[x][y] != 'o') { int d = mp[x][y] - '0'; dis[s][d] = tmp.t + 1; } node nd; nd.x = x; nd.y = y; nd.t = tmp.t + 1; q.push(nd); } } } int p[] = {0,1,2,3,4,5,6,7,8,9}; int main() { int n; cin >> n; getchar(); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) cin >> mp[i][j]; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { if(mp[i][j] != '.' && mp[i][j] != 'x') { int d = mp[i][j] == 'o' ? 10 : mp[i][j] - '0'; bfs(i,j,d); } } int res = 1e8; do{ int ans = dis[10][p[0]] + dis[10][p[9]]; for(int i = 0; i < 9; i++) ans += dis[p[i]][p[i+1]]; res = min(res,ans); }while(next_permutation(p,p+10)); cout << res <<endl; return 0; }
/* 10 o......0.. ...x..1... .x..2..x.. .3...x..4. .x..5.x... ..x....x.. .....x..6. .x.x..7... .8....xx.. ..x..x9... */