CSU 1726 你经历过绝望吗?两次! [BFS]

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;
}

 

posted on 2017-08-01 21:07  FTA_Macro  阅读(118)  评论(0编辑  收藏  举报

导航