hdu 1026 反向 bfs() + 前驱保存

做了4个小时,不容易啊,特别是路径保存,特别郁闷 ,最后终于想到了方法,

题意:就是从一点(0,0)——》(n,m),中途会遇见很多的情况:'x'----->陷阱,'.'------>load,'',数字1~9表示怪兽的血量,也就是你要停留几秒,很简单的bfs()+priority_queue,但是,路径保存,不好想,你需要记录当前最犹节点的前驱节点;然后反向bfs()
#include<stdio.h>
#include<string.h>
#include<queue>
#include<malloc.h>
#include<iostream>
using namespace std;
char map[136][136];   //地图
int vis[141][141];    //标记
int n,m;
typedef struct Node
{
    int x,y,step;
}aa;
struct cmp
{
   bool operator()(aa a,aa b)
   {
       return a.step>b.step;
   }
};
struct N
{
    int x,y;
}pre[101][101];
priority_queue <aa,vector<aa>,cmp> Q;//   优先队列
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int bfs()
{

    while(!Q.empty())
    {
        aa Ac=Q.top();
        aa bb;
        Q.pop();
        for(int i=0;i<4;i++)
        {
            int x = Ac.x + dx[i];
            int y = Ac.y + dy[i];
            if(x==1&&y==1)
            {
                pre[x][y].x = Ac.x;   //记录路径
                pre[x][y].y = Ac.y;
                return Ac.step + map[x][y];
            }

            if(map[x][y]!=-1&&!vis[x][y])
            {
               /*  此为精华*/
                pre[x][y].x = Ac.x;
                pre[x][y].y = Ac.y;
              /*  此为精华*/
                vis[x][y] = 1;
                bb.x = x;
                bb.y = y;
                bb.step = Ac.step+map[x][y];
                Q.push(bb);
            }

        }
    }
    return -1;
}
int main()
{

    while(cin>>n>>m)
    {
        while(!Q.empty())Q.pop();
        memset(map,-1,sizeof(map));
        memset(vis,0,sizeof(vis));
        getchar();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
            char c = getchar();
            switch(c)
            {
                case'X':map[i][j] = -1;break;
                case '.':map[i][j] = 1;break;
            }
            if(c>'0'&&c<='9')
            map[i][j] = c - '0'+1;    // 地图装换
            }
            getchar();
        }
       vis[n][m] = 1;
       aa bb;
       bb.x = n;
       bb.y = m;
       bb.step = map[n][m];   //反向  bfs();
       Q.push(bb);
       int num = bfs();
       if(num==-1)
       puts("God please help our poor hero.") ;
       else
       {
       printf("It takes %d seconds to reach the target position, let me show you the way.\n",num-1);
        int x = 1,y = 1;
        int cn = 1;
        while(1)
        {
            printf("%ds:",cn++);
            int tx = pre[x][y].x;  //路径输出
            int ty = pre[x][y].y;
            printf("(%d,%d)->(%d,%d)\n",x-1,y-1,tx-1,ty-1);
            if(map[tx][ty]>1)
            for(int i=1;i<map[tx][ty];i++)
            printf("%ds:FIGHT AT (%d,%d)\n",cn++,tx-1,ty-1);
            if(tx==n&&ty==m)break;
            x = tx;
            y = ty;
        }
       }
       puts("FINISH");

    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值