脱离地牢(阅读理解、、、)

问题 B: 脱离地牢

时间限制: 5 Sec  内存限制: 128 MB
提交: 68  解决: 8
[提交] [状态] [命题人:外部导入]

题目描述

在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活。

他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要把它们溶化,Satan就能吸收其精华大增自己的魔力。

于是有一天他趁二人不留意,把他们带到了自己的地牢,分别困在了不同的地方。然后Satan念起了咒语,准备炼狱,界时二人都将葬身于这地牢里。

危险!Paris与Helen都知道了Satan的意图,他们要怎样才能打败魔王,脱离地牢呢?

Paris想起了父王临终前给他的备忘本,原来他早已料到了Satan的野心,他告诉Paris只要把两块魔法石合在一起,念出咒语,它们便会放出无限的光荣,杀死魔王,脱离地牢,而且本子上还附下了地牢的地图,Paris从中了解到了Helen的位置所在。

于是他决定首先要找到Helen,但是他发现这个地牢很奇怪,它会增强二人魔法石所带的磁力大小,而且会改变磁力的方向。这就是说,每当Paris向南走一步,Helen有可能会被石头吸引向北走一步。

而这个地狱布满了岩石与熔浆,Paris必须十分小心,不仅他不能走到岩石或熔浆上,而且由于他行走一步,Helen的位置也会改变,如果Helen碰到岩石上,那么她将停留在原地,但如果Helen移动到了熔浆上,那么她将死去,Paris就找不到她了。

Paris仔细分析了地图,他找出了一条最快的行走方案,最终与Helen相聚。他们一起念出了咒语“·#¥%^…*&@!”,轰隆一声,地牢塌陷了,他们又重见光明…

 

输入

输入数据第一行为两个整数n,m(3<=n,m<=20),表示地牢的大小,n行m列。
接下来n行,每行m个字符,描述了cf地牢的地图,“.”代表通路,“#”代表岩石,“!”代表熔浆,“H”表示Helen,“P”表示Paris。
输入保证地牢是封闭的,即四周均是岩石或熔浆。
接下来一行有四个字符“N”(北),“S”(南),“W”(西),“E”(东)的排列,表示Paris分别向NSWE四个方向走时Helen受磁石磁力影响的移动方向。
 

 

输出

输出只有一行,如果Paris能找到Helen,输出一整数d,为Paris最少需要行走的步数;如果Paris在255步之后仍找不到Helen,则输出“Impossible”。

注意相遇是指Paris与Helen最终到达同一个格子,或者二人在相邻两格移动后碰到了一起,而后者的步数算他们移动后的步数。

 

样例输入

复制样例数据

5 5
#####
#H..#
#.!.#
#.#P#
#####
WNSE

样例输出

5

 

[提交][状态]

 

告诉你第一个人走北第二个人会往南(题目告诉你往哪走)走

求两人相遇最下步数(超过255步Impossible)

 

 

写个bfs,出了各种毛病

 

相遇两种是:

1,走到同一个格子

2,原本相邻,走后位置互换(相当于两人在半个格子处相遇了)

 

我出错就出在,我以为是第一个人先走,然后第二个人后走

(那样的话,第一个人可以先到第二个人的位置,而第二个人不必前往第一人的位置),

实际上这里应该看成同时进行的

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3+7,mod = 1e9+7;
char mmp[25][25],key[5];
int n,m,len;
struct person{
    int x,y;
    bool operator == (const person &p)const{
        return x==p.x&&y==p.y;
    }
};
struct node{
    person H,P;
    int step;
};
char s[] = "NSWE";
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int xd[4],yd[4];
bool vis[30][30][30][30];
bool sovle(){
    for(int i=1;i<=n;i++)scanf("%s",mmp[i]+1);
    scanf("%s",key);
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++)
        if(key[i] == s[j]){
            xd[i] = dx[j];
            yd[i] = dy[j];
        }
    }
    node Start;
    Start.step = 0;
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){
        if(mmp[i][j] == 'H'){
            Start.H.x = i,Start.H.y = j;
            mmp[i][j] = '.';
        }
        if(mmp[i][j] == 'P'){
            Start.P.x = i,Start.P.y = j;
            mmp[i][j] = '.';
        }
    }
    queue<node> Q;
    Q.push(Start);
    while(!Q.empty()){
        node Ft = Q.front();
        Q.pop();
        vis[Ft.H.x][Ft.H.y][Ft.P.x][Ft.P.y] = 1;
        if(Ft.step < 255){
            Ft.step++;
            for(int i=0;i<4;i++){
                node Tx = Ft;
                Tx.P.x += dx[i];
                Tx.P.y += dy[i];
                if(mmp[Tx.P.x][Tx.P.y] != '.')continue;

                Tx.H.x += xd[i];
                Tx.H.y += yd[i];

                if(mmp[Tx.H.x][Tx.H.y] != '.'){
                    if(mmp[Tx.H.x][Tx.H.y] == '!')
                        continue;
                    Tx.H.x -= xd[i];
                    Tx.H.y -= yd[i];
                }
                if(Tx.H == Tx.P || (Tx.H == Ft.P && Tx.P == Ft.H))
                    return 0*printf("%d\n",Ft.step);
                if(!vis[Tx.H.x][Tx.H.y][Tx.P.x][Tx.P.y])
                    Q.push(Tx);
            }
        }
    }
    return 0*puts("Impossible");
}
int main(){
    scanf("%d%d",&n,&m);
    sovle();
    return 0;
}

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值