EOJ1839

恶魔之城(数据结构)

Time Limit:1000MSMemory Limit:30000KB
Total Submit:376Accepted:152 Special Judge

Description

小强生日就要到了,partychen为了送给小强一个特别的礼物,决定到恶魔之城去偷走他们的镇城之宝--月亮之石.partychen已经从江湖百晓生处得到了恶魔之城的地图.根据地图的描述,恶魔之城是一个标准的n*m大小的一个悬在空中的城堡,里面有可以走的路,也有一些陷阱,如果人踏入陷阱那么将被恶魔吃掉,如果不小心踏出这个城堡,那么就将尸骨无存.partychen去城之前买了两个传送,第一个传送将把partychen安全的送往入口.第二个在拿到月亮之石的地方使用,安全的把partychen送回地面.由于时间紧迫,partychen能力有限,希望天才的你帮助他计算一下从入口安全到达到月亮之石的所在地最快需要多少步.并且帮他算出应该怎么走步数最小.当然可能有很多种走法,你只要输出任意可行的一种就可以了.

Input

第一行2个数n,m(0<n,m<=200),代表城的长和宽,因此城的左上角坐标为(0,0),右下角的坐标为(n-1,m-1).然后n行,每行m个字符,
'S'代表城的入口;
'E'代表月亮之石的地方;
'*'代表陷阱,一旦走进去将被恶魔吃掉;
'.'代表安全的路.

Output

如果不能安全达到出口就输出-1.
如果能够安全到达出口,第一行输出最小的步数D.后面D+1行输出从入口到达月亮之石的所在地的路径.每行两个整数代表该点的坐标(包括起点和终点坐标)

Sample Input

4 4
S...
*..*
..*.
...E

Sample Output

6
0 0
0 1
1 1
2 1
3 1
3 2

3 3

方品  10121540117

 

题目:EOJ1839

 

题目分析:

Bfs求出最短路径长度并输出其路径,用队列实现bfs,并用一个路径数组保存每个节点上一个节点的坐标,则可在完成bfs搜索后,根据存储的路径倒推出之前的路径。

 

 

AC代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <string>

#include <vector>

#include <queue>

#include <algorithm>

 

using namespace std;

 

char map[205][205];

bool visited[205][205];

int dx[]={-1,1,0,0},dy[]={0,0,-1,1};

int ans[40002][2]={};

 

struct Node{

   int x,y,step;

};

 

struct Path{

   int x,y;

}path[205][205];

 

int bfs(int x,int y,int n,int m){

   Node a,next;

   a.x=x;a.y=y;a.step=0;

   path[x][y].x=path[x][y].y=-1;

   queue<Node> q;

   q.push(a);

   while(!q.empty()){

       a=q.front();

       q.pop();

       if(map[a.x][a.y]=='E'){

           return a.step;

       }

        for(int i=0;i<4;++i){

           next.x=a.x+dx[i];

           next.y=a.y+dy[i];

           next.step=a.step+1;

           if(0<=next.x && next.x<n && 0<=next.y&& next.y <m && !visited[next.x][next.y] &&map[next.x][next.y]!='*'){

                q.push(next);

                path[next.x][next.y].x=a.x;

                path[next.x][next.y].y=a.y;

                visited[next.x][next.y]=true;

           }

       }

    }

   return -1;

}

 

int main()

{

   int n,m,i,j,x,y,tx,ty;

   memset(visited,false,sizeof(visited));

   memset(path,-1,sizeof(path));

   scanf("%d%d",&n,&m);

   for(i=0;i<n;++i){

       scanf("%s",map[i]);

       for(j=0;j<m;++j){

           if(map[i][j]=='S'){

                x=i;y=j;

           }

           if(map[i][j]=='E'){

                tx=i;ty=j;

           }

       }

    }

   visited[x][y]=true;

   int res=bfs(x,y,n,m);

   printf("%d\n",res);

   if(res!=-1){

       int a=tx,b=ty;

       int k=0;

       while(a!=x || b!=y){

           ans[k][0]=path[a][b].x;

           ans[k][1]=path[a][b].y;

           a=ans[k][0];

           b=ans[k++][1];

       }

       for(--k;k>=0;--k)

           printf("%d %d\n",ans[k][0],ans[k][1]);

       printf("%d %d\n",tx,ty);

    }

   return 0;

}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值