UVA11624-Fire!

题目链接:UVA11624

也是比较坑的一道题目

首先读题,发现Input 最后一句话,there will be exactly one J in each test case;

这句话的意思说,每个测试点有且只有一个Joe,那么与其相对的Fire,没有特别注明,

也就是说每个测试点不确定有几个fire,这是第一个坑点。

第二个,思路,先把所有的起火点跑一遍,得到每个点的最早起火时间图F。在用Joe对F跑BFS即可。

第三个,要注意一个细节哦,大体上是Joe,走的每个点的时间都要小于起火时间,要注意特判一下,

如果这个点不会起火,但是这个点又不是墙,那么这个点是可以走的。这个点要特别注意-WA了两小时。

AC代码  

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;

const int maxn=1100;
int f[maxn][maxn];
char mp[maxn][maxn];
int n,m,fx,fy,jx,jy;
bool vis[maxn][maxn];
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node{
    int x,y;
    int time;
};

void bfs_fire(){
    queue<node> q;
    node t1,t2,t3;
    //memset(vis,false,sizeof(vis));
  //  memset(f,-1,sizeof(f));
    while(!q.empty()) q.pop();
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(mp[i][j]=='F'){
                t1.x=i;
                t1.y=j;
                t1.time=0;
               // vis[i][j]=1;
                f[i][j]=0;
                q.push(t1);
            }
        }
    }
    while(!q.empty()){
        t2=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            t3.x=t2.x+dir[i][0];
            t3.y=t2.y+dir[i][1];
            if(f[t3.x][t3.y]!=-1) continue;
            if(mp[t3.x][t3.y]=='#') continue;
            if(t3.x>=n||t3.x<0||t3.y>=m||t3.y<0) continue;
          //  if(vis[t3.x][t3.y]) continue;

            f[t3.x][t3.y]=t2.time+1;
            t3.time=t2.time+1;
            //vis[t3.x][t3.y]=1;
            q.push(t3);
        }
    }
    return;
}

int bfs_joe(int x,int y){
    queue<node> q;
    memset(vis,false,sizeof(vis));
    node t1,t2,t3;
    while(!q.empty()) q.pop();
    t1.x=x;
    t1.y=y;
    t1.time=0;
    vis[x][y]=1;
    q.push(t1);
    while(!q.empty()){
        t2=q.front();
        q.pop();
        int cx,cy;
        cx=t2.x;
        cy=t2.y;
        if(cx==0||cx==n-1||cy==0||cy==m-1){
            return t2.time+1;
        }
        for(int i=0;i<4;i++){
            t3.x=t2.x+dir[i][0];
            t3.y=t2.y+dir[i][1];
            if(t3.x>=n||t3.x<0||t3.y>=m||t3.y<0) continue;
            if(mp[t3.x][t3.y]=='#') continue;
            if(!vis[t3.x][t3.y]){
                if((f[t3.x][t3.y]>=0&&t2.time+1<f[t3.x][t3.y])||f[t3.x][t3.y]==-1){
                    vis[t3.x][t3.y]=1;
                    t3.time=t2.time+1;
                    q.push(t3);
                }
            }
        }
    }
    return -1;
}

int main(){
    //freopen("J.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--){
        memset(f,-1,sizeof(f));
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++){
            scanf("%s",mp[i]);
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(mp[i][j]=='J'){
                    jx=i;
                    jy=j;
                    break;
                }
            }
        }
        bfs_fire();
        /*
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                printf("%d ",f[i][j]);
            }puts("");
        }

       // */
        int ans=bfs_joe(jx,jy);
        if(ans==-1) printf("IMPOSSIBLE\n");
        else printf("%d\n",ans);
    }
    return 0;
}

 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值