题意:M行N列的矩阵。Y:起点,T:终点。S、R不能走,走B花费2,走E花费1.求Y到T的最短时间。
三种解法。♪(^∇^*)
//解法一:暴力
//157MS #include#include #include #include #include<string> #include #include #include #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int mod = 1e9+7; const int N = 305; int a[N][N], b[N][N]; char s[N][N]; int m, n; int main() { int i, j; while(~scanf("%d%d", &m, &n), n || m) { getchar(); int sx, sy, ex, ey; for(i = 0; i < m; ++i) scanf("%s", s[i]); for(i = 0; i < m; ++i) { for(j = 0; j < n; ++j) { if(s[i][j] == 'R' || s[i][j] == 'S') a[i][j] = inf; else if(s[i][j] == 'B') a[i][j] = 2; else a[i][j] = 1; if(s[i][j] == 'Y') {sx = i; sy = j;} else if(s[i][j] == 'T') {ex = i; ey = j;} } } CLR(b, inf); b[sx][sy] = 0; while(1) { bool f = 0; for(i = 0; i < m; ++i) { for(j = 0; j < n; ++j) { if(b[i][j] == inf) continue; if(i > 0 && b[i-1][j] > b[i][j] + a[i-1][j]) { b[i-1][j] = b[i][j] + a[i-1][j]; f = 1; } if(i < m-1 && b[i+1][j] > b[i][j] + a[i+1][j]) { b[i+1][j] = b[i][j] + a[i+1][j]; f = 1; } if(j > 0 && b[i][j-1] > b[i][j] + a[i][j-1]) { b[i][j-1] = b[i][j] + a[i][j-1]; f = 1; } if(j < n-1 && b[i][j+1] > b[i][j] + a[i][j+1]) { b[i][j+1] = b[i][j] + a[i][j+1]; f = 1; } } } if(!f) break; } if(b[ex][ey] != inf) printf("%d\n", b[ex][ey]); else printf("-1\n"); } return 0; }
//解法二:bfs+优先队列
//16MS #include#include #include #include #include<string> #include #include #include #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int mod = 1e9+7; const int N = 305; struct node { int x, y; int w; node(int x = 0, int y = 0, int w = 0):x(x),y(y),w(w){} bool operator < (const node&r) const { return w > r.w; } }; char s[N][N]; bool vis[N][N]; int dx[] = {1,0,-1,0}; int dy[] = {0,1,0,-1}; int m, n; int ans; int sx, sy; bool check(int x, int y) { if(x < 0 || x >= m || y < 0 || y >= n) return false; if(s[x][y] == 'S' || s[x][y] == 'R' || vis[x][y]) return false; return true; } int bfs() { CLR(vis, 0); priority_queue q; q.push(node(sx, sy, 0)); vis[sx][sy] = 1; while(!q.empty()) { node t = q.top(); q.pop(); //vis[t.x][t.y] = 0; if(s[t.x][t.y] == 'T') { ans = t.w; return true; } for(int i = 0; i < 4; ++i) { int x = t.x + dx[i]; int y = t.y + dy[i]; if(check(x, y)) { int w = t.w + 1; if(s[x][y] == 'B') w++; vis[x][y] = 1; q.push(node(x, y, w)); } } } return false; } int main() { int i, j; while(~scanf("%d%d", &m, &n), n || m) { getchar(); for(i = 0; i < m; ++i) scanf("%s", s[i]); for(i = 0; i < m; ++i) { for(j = 0; j < n; ++j) { if(s[i][j] == 'Y') {sx = i; sy = j; break;} } } if(bfs()) printf("%d\n", ans); else printf("-1\n"); } return 0; }
//解法三:bfs,不用优先队列,搜到B时,把它变换成E再放入队列,重新取下一个队首继续搜索,这样就不用优先队列,用普通队列也能做啦
//32MS #include#include #include #include #include<string> #include #include #include #define CLR(a,b) memset((a),(b),sizeof((a))) using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int mod = 1e9+7; const int N = 305; struct node { int x, y; int w; node(int x = 0, int y = 0, int w = 0):x(x),y(y),w(w){} }; char s[N][N]; bool vis[N][N]; int dx[] = {1,0,-1,0}; int dy[] = {0,1,0,-1}; int m, n; int ans; int sx, sy; bool check(int x, int y) { if(x < 0 || x >= m || y < 0 || y >= n) return false; if(s[x][y] == 'S' || s[x][y] == 'R' || vis[x][y]) return false; return true; } int bfs() { CLR(vis, 0); queue q; q.push(node(sx, sy, 0)); vis[sx][sy] = 1; while(!q.empty()) { node t = q.front(); q.pop(); if(s[t.x][t.y] == 'T') { ans = t.w; return true; } if(s[t.x][t.y] == 'B') { t.w++; s[t.x][t.y] = 'E'; q.push(t); continue; } for(int i = 0; i < 4; ++i) { int x = t.x + dx[i]; int y = t.y + dy[i]; if(check(x, y)) { int w = t.w + 1; vis[x][y] = 1; q.push(node(x, y, w)); } } } return false; } int main() { int i, j; while(~scanf("%d%d", &m, &n), n || m) { getchar(); for(i = 0; i < m; ++i) scanf("%s", s[i]); for(i = 0; i < m; ++i) { for(j = 0; j < n; ++j) { if(s[i][j] == 'Y') {sx = i; sy = j; break;} } } if(bfs()) printf("%d\n", ans); else printf("-1\n"); } return 0; }