NEFU 1191 BFS

这篇博客介绍了NEFU比赛中的1191题,涉及到的时间限制为2000ms,内存限制为65535K。内容包括问题描述、输入输出格式以及样例,为参赛者提供了解题思路。
摘要由CSDN通过智能技术生成

平行宇宙

Problem:1191
Time Limit:2000ms
Memory Limit:65535K

Description

小k是时空贸易者,他经常在两个平行宇宙之间往来经商,现在他要从S点到达E点,问最少需要多长时间。(已知小k在同一个宇宙中只能向上下左右四个方向移动,每次移动需要1个单位时间,且不能在危险小行星带'#'中移动,遇到黑洞'O'时,他会被瞬间吸入另一个宇宙的对应的同一位置,比如从一个宇宙的黑洞处(2,2)必须且只能移动到另一个宇宙的(2,2)位置)

Input

多组输入数据,每组数据第一行包含两个整数n,m(2<=n,m<=1000),表示两个宇宙的大小。
接下来n行表示第一个宇宙,再接下来n行表示第二个宇宙。

Output

每组数据输出一个整数,表示最短时间,如果不能到达目的地,输出-1

Sample Input

4 6
#S##E#
#.##..
#.O.#.
#####.

######
#.####
#..O##
##...O

Sample Output

11

Hint

Source

by 张猛治
第一眼看的时候很难,其实就是比较裸的BFS。BFS时做好两个图中间的跳转就好。学长的标程很牛,直接按题意解的,我是变了一下两个宇宙之间加了一堵墙。然后跳转就好。

#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
typedef struct {
    int x;
    int y;
    int step;
}Node;
int dir_x[]={-1,0,0,1};
int dir_y[]={0,-1,1,0};
Node st,en;
int ans,n,m;
char maze[2010][1010];
void bfs(){
    ans=0;
    queue <Node> a;
    while(!a.empty()) a.pop();
    a.push(st);

    Node temp,temp1,now;
    while(!a.empty()){
        temp=a.front();a.pop();
        if(maze[temp.x][temp.y]=='#'||maze[temp.x][temp.y]=='O') continue;
        if(maze[temp.x][temp.y]=='E') {ans=temp.step;return ;}
        for(int i=0;i<4;i++){
            now.x=temp.x+dir_x[i];
            now.y=temp.y+dir_y[i];
            now.step=temp.step+1;
            if(now.x<0||now.y<0||now.x>2*n||now.y>=m||maze[now.x][now.y]=='#'){
                continue;
            }else if(maze[now.x][now.y]=='O'){
                if(now.x>n)
                    temp1.x=now.x-(n+1);
                else
                    temp1.x=now.x+(n+1);
                    temp1.y=now.y;temp1.step=now.step;
                    a.push(temp1);
                    maze[now.x][now.y]='#';
            }else{
                a.push(now);
            }
        }
        maze[temp.x][temp.y]='#';
    }
    ans=-1;
    return ;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
        getchar();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%c",&maze[i][j]);
                if(maze[i][j]=='S'){
                    st.x=i;
                    st.y=j;
                    st.step=0;
                }
            }
            getchar();
        }
        getchar();
        for(int j=0;j<m;j++)
            maze[n][j]='#';
        for(int i=n+1;i<=2*n;i++){
            for(int j=0;j<m;j++){
                scanf("%c",&maze[i][j]);
                if(maze[i][j]=='S'){
                    st.x=i;
                    st.y=j;
                    st.step=0;
                }
            }
            getchar();
        }
        bfs();
        cout<<ans<<endl;
    }
}


学长的:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<queue>
using namespace std;
char map[2][1005][1005];
int dis[2][1005][1005];
int mi[4]={0,0,-1,1},mj[4]={1,-1,0,0};
struct D {
    int t,i,j;
    D(int tt,int ii,int jj) {
        t = tt; i = ii; j = jj;
    }
};
int main() {
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF) {
        memset(dis,-1,sizeof(dis));
        int st=-1,si,sj;
        for(int t=0;t<2;t++) {
            for(int i=0;i<n;i++) {
                scanf("%s",map[t][i]);
                if(st!=-1) continue;
                for(int j=0;j<m;j++) {
                    if(map[t][i][j]=='S') {
                        st = t;
                        si = i;
                        sj = j;
                    }
                }
            }
        }

        queue<D> que;
        dis[st][si][sj]=0;
        que.push(D(st,si,sj));
        while(!que.empty()) {
            D tmp = que.front();
            que.pop();
            int t=tmp.t,i=tmp.i,j=tmp.j;
            int nt = t;
            if(map[t][i][j]=='O') {
                nt = !nt;
                if(dis[nt][i][j]==-1&&map[nt][i][j]!='O'&&map[nt][i][j]!='#') dis[nt][i][j]=dis[t][i][j];
                else continue;
            }
            for(int k=0;k<4;k++) {
                int ti=i+mi[k],tj=j+mj[k];
                if(ti<0||ti>=n||tj<0||tj>=m||map[nt][ti][tj]=='#'||dis[nt][ti][tj]!=-1) continue;
                if(map[nt][ti][tj]=='E') {
                    printf("%d\n",dis[nt][i][j]+1);
                    goto NEXT;
                }
                dis[nt][ti][tj] = dis[nt][i][j]+1;
                //printf("%d %d %d %d\n",nt,ti,tj,dis[nt][ti][tj]);
                que.push(D(nt,ti,tj));
            }
        }
        puts("-1");
        NEXT:;
    }
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值