hrbust 2159【BFS水题】

火势蔓延
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 26(13 users)Total Accepted: 13(13 users)Rating: Special Judge: No
Description

饥荒游戏里可以用干草建造草墙,草墙是易燃的,一旦周围有火就会被引燃。Mr Liang玩饥荒的时候,好不容易建造了一些草墙,某天下雨打雷,突然一道闪电劈到草墙上,然后辛辛苦苦造的一片草墙就被烧没了。Mr Liang很不甘心,又造了一片草墙, 这次他准备了一个灭火器,现在他想知道草墙多长时间会被烧掉50%以上好让他知道有多长的反应时间能挽救剩下的草墙。他的草墙是建在一块N*N的空地上的,火势的蔓延方式是沿着上下左右方向的且需要的时间是1,即如果在第T时刻草墙x,y着火,那么在T+1时刻处在(x+1,y),(x-1,y),(x,y+1),(x,y-1)的草墙也会着火。

闪电只有一道,但是闪电会引起一个小范围内的草墙都起火,具体是:如果闪电劈到了x,y位置,那么处于(x,y),(x-1,y),(x+1,y),(x,y-1),(x,y+1)的草墙都会起火。

如果记闪电劈到某处草墙并引起了草墙起火的时刻为时刻0,那么Mr Liang 想知道在从哪个(整数)时刻起草墙有50%以上着火了。

Input

第一行一个整数Q(Q<=10)表示测试数据的组数。

每组测试数据,第一行N(N<=100)表示一片空地的边长;然后给出一个N*N的矩阵,其中,#表示空地处有一个草墙;最后两个整数x,y表示闪电劈到了第x行第y列的位置。

Output

一个整数表示答案,如果并不能引起50%以上的草墙起火则输出-1。

Sample Input

3

2

##

##

1 1

3

#.#

...

#.#

2 2

4

####

...#

#..#

####

1 1

Sample Output

0

-1

4

Source
2014暑假集训练习赛(8月13日)

刷理工rating路漫漫~

思路:用两个计数器,分别统计当前蔓延烧完了的#块数和一共的#数,如果前者>后者/2,那么就return;并且输出当前走的步数;

AC代码:

#include<stdio.h>//写的急有点挫0.0
#include<string.h>
#include<queue>
using namespace std;
struct zuobiao
{
    int x,y,output;
}now,nex;
int fx[4]={0,0,-1,1};
int fy[4]={1,-1,0,0};
char  a[105][105];
int vis[105][105];
int cont;
int cont2;
int n;
void bfs(int x,int y)
{
    memset(vis,0,sizeof(vis));
    queue<zuobiao >s;
    if(a[x][y]=='#')
    {
        now.x=x;
        now.y=y;
        now.output=0;
        s.push(now);
        vis[x][y]=1;
        cont2++;
        if(cont2>cont/2)
        {
            printf("%d\n",now.output);
            return ;
        }
    }
    for(int i=0;i<4;i++)
    {
       // printf("%d %d\n",s.size(),cont2);
        int xx=x+fx[i];
        int yy=y+fy[i];
        now.x=xx;
        now.y=yy;
        now.output=0;
        if(a[xx][yy]=='#'&&xx>=0&&xx<n&&yy>=0&&yy<n)
        {
            s.push(now);
            vis[now.x][now.y]=1;
            cont2++;
        }
        if(cont2>cont/2)
        {
            printf("%d\n",now.output);
            return ;
        }
    }
    while(!s.empty())
    {
        now=s.front();
        s.pop();
        for(int i=0;i<4;i++)
        {
            nex.x=now.x+fx[i];
            nex.y=now.y+fy[i];
            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<n&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]=='#')
            {
                vis[nex.x][nex.y]=1;
                nex.output=now.output+1;
                s.push(nex);
                cont2++;
                if(cont2>cont/2)
                {
                    printf("%d\n",nex.output);
                    return ;
                }
            }
        }
    }
    printf("-1\n");
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        cont=0;
        cont2=0;
        for(int i=0;i<n;i++)
        {
            scanf("%s",a[i]);
            for(int j=0;j<n;j++)
            {
                if(a[i][j]=='#')cont++;
            }
        }
        int x,y;
        scanf("%d%d",&x,&y);
        x--;
        y--;
        bfs(x,y);
    }
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值