一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。
标签:
Description
一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。
Input
每组数据第一行一个n,表示尺寸,2 <= n <= 100。
接下来n行每行n个0~9的字符,或S表示起点,E表示终点,S和E的运动规则与0相同。整个地图只有一个S和一个E。
Output
每组数据输出一个数,占一行,表示起点到终点可以花费的最短时间。
如果无法到达重点,输出"Oh No!"
Sample Input
5 0S100 00131 00300 00000 003E0 3 S12 010 10E
Sample Output
4 Oh No!
这个就不解释题意了,直接贴AC代码!(弱弱的问下应该都能看懂中文吧╭(′▽`)╯)
#include <iostream> #include <stdio.h> #include <queue> #include <string.h> #define N 110 using namespace std; int vis[N][N], dis[N][N]; int x1, x2, y1, y2, n; int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0}; char map[N][N]; void bfs(int x, int y) { int ans = n * n; int tx, ty, i, j, k, ttx, tty; queue<pair<int, int> > Q; Q.push(make_pair(x, y)); vis[x][y] = 1; dis[x][y] = 1; while(!Q.empty()) { ans--; if(!ans) break; tx = Q.front().first, ty = Q.front().second; if(tx == x2 && ty == y2) { printf("%d\n", dis[x2][y2] - 1); return ; } Q.pop(); if(map[tx][ty] != ‘1‘) { for(k = 0; k < 4; k++) { ttx = tx + dx[k]; tty = ty + dy[k]; if(!dis[ttx][tty] && map[ttx][tty] != ‘1‘ && ttx >= 0 && ttx < n && tty >= 0 && tty < n) { vis[ttx][tty] = 1; dis[ttx][tty] = dis[tx][ty] + 1; Q.push(make_pair(ttx, tty)); if(map[ttx][tty] >= ‘2‘ && map[ttx][tty] <= ‘9‘)/*注意这应该是一次性的把2~9相同的数字都入队*/ { for(i = 0; i < n; i++) for(j = 0; j < n; j++) if(map[i][j] == map[ttx][tty] && !dis[i][j]) { vis[i][j] = 1; dis[i][j] = dis[ttx][tty]; Q.push(make_pair(i, j)); } } } } } } printf("Oh No!\n"); } int main() { int i; while(~scanf("%d", &n)) { memset(vis, 0, sizeof(vis)); memset(dis, 0, sizeof(dis)); getchar(); for(i = 0; i < n; i++) { for(int j = 0; j < n; j++) { map[i][j] = getchar(); if(map[i][j] == ‘1‘) vis[i][j] = 1; else if(map[i][j] == ‘S‘) x1 = i, y1 = j; else if(map[i][j] == ‘E‘) x2 = i, y2 = j; } getchar(); } bfs(x1, y1); } return 0; }
标签:
原文地址:http://www.cnblogs.com/yu0111/p/4727654.html