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
题目大意:中文就没什么好说了,提一下猪被救的条件。猪如果可以移动到给出图形边缘位置,那么它就获救。求需要拆除的废墟的最少数量。
大致思路:简单的BFS,猪从起点开始,每次走的时候遍历四个方向,一直到边缘位置即可。定义一个结构体节点,用优先队列来保存节点。优先级队列如果插入的节点是结构体类型,则要在结构体中重载比较操作符函数。当时做的时候还在想,怎么判断拆的废墟是最少的,写的时候发现BFS借助队列本来就是可以找最少量的。。。详见代码。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include <queue> #define maxn 105 using namespace std; int n,m; int mark[maxn][maxn]; char ma[maxn][maxn]; int dX[4]={0,0,-1,1};//四个方向,也可以开二维数组存 int dY[4]={-1,1,0,0}; struct Node { int x,y,step; friend bool operator <(Node a,Node b)//可以当模板记住 { return a.step>b.step; } }; void bfs(int x,int y) { int step; priority_queue<Node> q; Node p1; p1.x=x; p1.y=y; p1.step=0; memset(mark,0,sizeof(mark)); mark[p1.x][p1.y]=1; q.push(p1); while(!q.empty()) { p1=q.top(); q.pop(); x=p1.x; y=p1.y; step=p1.step; if(x==0||y==0||x==n-1||y==m-1) { cout<<step<<endl; return; } Node p2; for(int i=0;i<4;i++) { p2.x=x+dX[i]; p2.y=y+dY[i]; p2.step=0; if(p2.x>=0&&p2.y>=0&&p2.x<n&&p2.y<m) { if(ma[p2.x][p2.y]==‘*‘) p2.step=step+1; else if(ma[p2.x][p2.y]==‘.‘) p2.step=step; else p2.step=-1; if(p2.step>=0&&mark[p2.x][p2.y]==0)//注意前一个判断条件,防止不可拆除的废墟被算在内 { mark[p2.x][p2.y]=1; q.push(p2); } } } } cout<<-1<<endl;//如果没走出,记得返回-1 } int main() { int T,sx,sy; scanf("%d",&T); while(T--) { scanf("%d%d", &n, &m); for (int i=0; i<n; ++i) scanf("%s", ma+i);//字符串的输入,用指针的形式 for(int i=0;i<n;i++) for(int j=0;j<m;j++) { if (ma[i][j] == ‘@‘)//找出起点 { sx = i; sy = j; } } bfs(sx,sy); } return 0; }
时间: 2024-12-21 06:05:02