1726: 你经历过绝望吗?两次!
Time Limit: 1 Sec Memory Limit: 128 Mb
Description
4月16日,日本熊本地区强震后,受灾严重的阿苏市一养猪场倒塌,幸运的是,猪圈里很多头猪依然坚强存活。当地15名消防员耗时一天解救围困的“猪坚强”。不过与在废墟中靠吃木炭饮雨水存活36天的中国汶川“猪坚强”相比,熊本的猪可没那么幸运,因为它们最终还是没能逃过被送往屠宰场的命运。
我们假设“猪坚强”被困在一个N*M的废墟中,其中“@”表示“猪坚强”的位置,“.”表示可以直接通过的空地,“#”表示不能拆毁的障碍物,“*”表示可以拆毁的障碍物,那么请问消防员至少要拆毁多少个障碍物,才能从废墟中救出“猪坚强”送往屠宰场?(当“猪坚强”通过空地或被拆毁的障碍物移动到废墟边缘时,视作被救出废墟)
Input
多组数据,第一行有一个整数T,表示有T组数据。(T<=100)
以下每组数据第一行有两个整数N和M。(1<=N,M<=100)
接着N行,每行有一个长度为M的字符串。
Output
一个整数,为最少拆毁的障碍物数量,如果不能逃离废墟,输出-1。
Sample Input
3
3 3
#
@*
3 4
#
@.*
*.
3 3
.#.
@
.#.
Sample Output
1
0
-1
Hint
Source
中南大学第十届大学生程序设计竞赛
题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1726
题解:直接BFS模板套用,再结合优先队列,以较少拆毁的障碍物数量来排序,若能逃离,就输出优先队列的top元素的step,若不能逃离,就输出-1。
AC代码:
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
struct node{
int step;
int x,y;
}p,q,w;
bool operator <(struct node a,struct node b){
return a.step>b.step;
}
int T,n,m,px,py,ans;
char map[110][110];
priority_queue<struct node>Q;
int vis[110][110];
int ppx[4]={0,1,0,-1};
int ppy[4]={1,0,-1,0};
void Init(){
while(!Q.empty()){
Q.pop();
}
memset(vis,0,sizeof(vis));
}
int BFS(){
q.step=0;
q.x=px;
q.y=py;
Q.push(q);
vis[q.x][q.y]=1;
while(!Q.empty()){
p=Q.top();
Q.pop();
if(p.x==0||p.x==n-1||p.y==0||p.y==m-1){
return p.step;
}
for(int i=0;i<4;i++){
w=p;
w.x+=ppx[i];
w.y+=ppy[i];
if(map[w.x][w.y]=='#'||w.x<0||w.y<0||w.x>=n||w.y>=m){
continue;
}
else if(map[w.x][w.y]=='*'&&vis[w.x][w.y]==0){
w.step+=1;
vis[w.x][w.y]=1;
Q.push(w);
}
else if(map[w.x][w.y]=='.'&&vis[w.x][w.y]==0){
vis[w.x][w.y]=1;
Q.push(w);
}
}
}
return -1;
}
int main(){
scanf("%d",&T);
while(T--){
Init();
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%s",map[i]);
for(int j=0;j<m;j++){
if(map[i][j]=='@'){
px=i;py=j;
}
}
}
if(px==0||px==n-1||py==0||py==m-1){
printf("0\n");
continue;
}
ans=BFS();
printf("%d\n",ans);
}
return 0;
}