题目来源:http://noi.openjudge.cn/ch0205/2727/
2727:仙岛求药
总时间限制: 1000ms 内存限制:65536kB
描述
少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶。叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。迷阵由M×N个方格组成,有的方格内有可以瞬秒李逍遥的怪物,而有的方格内则是安全。现在李逍遥想尽快找到仙药,显然他应避开有怪物的方格,并经过最少的方格,而且那里会有神秘人物等待着他。现在要求你来帮助他实现这个目标。
下图显示了一个迷阵的样例及李逍遥找到仙药的路线.
输入
输入有多组测试数据. 每组测试数据以两个非零整数 M 和 N 开始,两者均不大于20。M 表示迷阵行数, N 表示迷阵列数。接下来有 M 行, 每行包含N个字符,不同字符分别代表不同含义:
1) ‘@’:少年李逍遥所在的位置;
2) ‘.’:可以安全通行的方格;
3) ‘#’:有怪物的方格;
4) ‘*’:仙药所在位置。
当在一行中读入的是两个零时,表示输入结束。
输出
对于每组测试数据,分别输出一行,该行包含李逍遥找到仙药需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药, 则输出 -1。
样例输入
8 8 .@##...# #....#.# #.#.##.. ..#.###. #.#...#. ..###.#. ...#.*.. .#...### 6 5 .*.#. .#... ..##. ..... .#... ....@ 9 6 .#..#. .#.*.# .####. ..#... ..#... ..#... ..#... #.@.## .#..#. 0 0
样例输出
10 8 -1
-----------------------------------------------------
解题思路
广度优先搜索
-----------------------------------------------------
代码
//D:仙岛求药 //总时间限制: 1000ms 内存限制: 65536kB //描述 //少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶。叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。迷阵由M×N个方格组成,有的方格内有可以瞬秒李逍遥的怪物,而有的方格内则是安全。现在李逍遥想尽快找到仙药,显然他应避开有怪物的方格,并经过最少的方格,而且那里会有神秘人物等待着他。现在要求你来帮助他实现这个目标。 //下图 显示了一个迷阵的样例及李逍遥找到仙药的路线. // //输入 //输入有多组测试数据. 每组测试数据以两个非零整数 M 和 N 开始,两者均不大于20。M 表示迷阵行数, N 表示迷阵列数。接下来有 M 行, 每行包含N个字符,不同字符分别代表不同含义: //1) ‘@’:少年李逍遥所在的位置; //2) ‘.’:可以安全通行的方格; //3) ‘#’:有怪物的方格; //4) ‘*’:仙药所在位置。 //当在一行中读入的是两个零时,表示输入结束。 //输出 //对于每组测试数据,分别输出一行,该行包含李逍遥找到仙药需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药, 则输出 -1。 //样例输入 //8 8 //.@##...# //#....#.# //#.#.##.. //..#.###. //#.#...#. //..###.#. //...#.*.. //.#...### //6 5 //.*.#. //.#... //..##. //..... //.#... //....@ //9 6 //.#..#. //.#.*.# //.####. //..#... //..#... //..#... //..#... //#.@.## //.#..#. //0 0 //样例输出 //10 //8 //-1 #include<fstream> #include<iostream> #include<queue> using namespace std; const int MAX = 20; char mat[MAX][MAX]; struct node{ int x,y; }; void surround(node a, int n, int m, deque<node> &path, bool *mark, int *len) { int x = a.x, y = a.y, xy = x*m+y; node b; if (x>0 && mat[x-1][y] != '#' && !mark[(x-1)*m+y]) { mark[(x-1)*m+y] = true; len[(x-1)*m+y] = len[xy]+1; b.x = x-1; b.y = y; path.push_back(b); } if (y>0 && mat[x][y-1] != '#' && !mark[x*m+(y-1)]) { mark[x*m+(y-1)] = true; len[x*m+(y-1)] = len[xy]+1; b.x = x; b.y = y-1; path.push_back(b); } if (x<n-1 && mat[x+1][y] != '#' && !mark[(x+1)*m+y]) { mark[(x+1)*m+y] = true; len[(x+1)*m+y] = len[xy]+1; b.x = x+1; b.y = y; path.push_back(b); } if (y<m-1 && mat[x][y+1] != '#' && !mark[x*m+y+1]) { mark[x*m+y+1] = true; len[x*m+y+1] = len[xy]+1; b.x = x; b.y = y+1; path.push_back(b); } } int bfs(int n, int m, int sx, int sy, int dx, int dy) { node s; s.x = sx; s.y = sy; int ans = -1; deque<node> path; bool *mark = new bool[n*m](); mark[sx*m+sy] = true; int *len = new int[n*m](); path.push_back(s); while(!path.empty()) { s = path.front(); if (s.x == dx && s.y == dy) { ans = len[dx*m+dy]; delete[] mark; delete[] len; return ans; } surround(s,n,m,path,mark,len); path.pop_front(); } delete[] mark; delete[] len; return -1; } int main() { #ifndef ONLINE_JUDGE ifstream fin("tm201601D.txt"); int n,m,i,j,sx,sy,dx,dy; while(fin >> n >> m) { if (n==0 && m==0) { break; } for (i=0; i<n; i++) { for (j=0; j<m; j++) { fin >> mat[i][j]; if(mat[i][j] == '@') { sx = i; sy = j; } else if(mat[i][j] == '*') { dx = i; dy = j; } } } cout << bfs(n,m,sx,sy,dx,dy) << endl; } fin.close(); #endif #ifdef ONLINE_JUDGE int n,m,i,j,sx,sy,dx,dy; while(cin >> n >> m) { if (n==0 && m==0) { break; } for (i=0; i<n; i++) { for (j=0; j<m; j++) { cin >> mat[i][j]; if(mat[i][j] == '@') { sx = i; sy = j; } else if(mat[i][j] == '*') { dx = i; dy = j; } } } cout << bfs(n,m,sx,sy,dx,dy) << endl; } #endif }