hdu 1026 Ignatius and the Princess I

本文介绍了一种改进的广度优先搜索(BFS)算法,该算法不仅能够找到从起点到终点的最短路径,还能记录下每一步的行走路径,并通过优先队列确保输出最短时间。适用于游戏地图寻路等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

备注:带路径的bfs
这道题与普通的bfs相比有3个要点:
1.hero将会在有数字的格子上停留,直接用个数组fright[105][105]来保存。
2.要输出他每走一步的路径。每走一步他的方向(后继)都是不确定的,但是
他的前驱是确定的。所以,保存前驱就好。
3.输出的是最短时间,bfs出来的是最短的路径却不是最短的时间,所以要用优先队列根据时间来排序。

总结一下就是bfs+优先队列+路径保存。

//带路径的广搜  后继记录前驱 
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int fright[105][105];
int visit1[105][105]; 
char a[105][105];
 struct Point{
    int x;
    int y;
 };
struct Node{
    int col;
    int row;
    int t;
};
struct cmp  
{  
     bool operator ()(Node x, Node y)  
    {  
        return x.t > y.t;//小的优先级高  
    }  
};  
Point pre[105][105];
Node first,en;
int nexted[4][2]={0,1,0,-1,1,0,-1,0};
int n,m;
int bfs()
{
    Node front,v;
    priority_queue<Node,vector<Node>,cmp> q;
    q.push(en);
    while(!q.empty())
    {
        //cout<<"进入"<<endl;
        front=q.top();//优先队列没有front方法。 
        q.pop();
        if(front.col==0&&front.row==0)
        {
        printf("It takes %d seconds to reach the target position, let me show you the way.\n",front.t);
        int x=front.col;
        int y=front.row;
        int key=1;
        pre[n-1][m-1].x=-1;
        while (pre[x][y].x != -1)    //不断寻找前驱直到到达终点  
            {  
                int tx = pre[x][y].x;  
                int ty = pre[x][y].y;  
                printf ("%ds:(%d,%d)->(%d,%d)\n", key++, x, y, tx, ty);  
                if (a[tx][ty] != '.')  
                    for (int i = 0; i < a[tx][ty] - '0'; i++)  
                        printf ("%ds:FIGHT AT (%d,%d)\n", key++, tx, ty);  
                x = tx;  
                y = ty;  
            }  

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

        v.col=front.col+nexted[i][0];
        v.row=front.row+nexted[i][1];
        v.t=front.t+fright[v.col][v.row]+1;
        if(visit1[v.col][v.row]==1)  continue;
        if(a[v.col][v.row]=='X') continue;
        if(v.col<0||v.row<0||v.col>=n||v.row>=m) continue;//刚开始忘了加等号,这样的小细节,可把我给害苦了。 
        q.push(v);
        //记录前驱。。 
        pre[v.col][v.row].x=front.col;
        pre[v.col][v.row].y=front.row;
        //````````````` 
        visit1[v.col][v.row]=1;
        }

    }
    return 0;
}
int main()
{
    int flag;//标记能不能走到 
    while(scanf("%d%d",&n,&m)==2)
    {
    memset(fright,0,sizeof(fright));
    memset(visit1,1,sizeof(visit1));
    memset(a,0,sizeof(a));
    memset(pre,0,sizeof(pre));
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
           cin>>a[i][j];
           visit1[i][j]=0;
            //if(a[i][j]=='X') {
              // for(int k=1;k<=9;k++)
                //visited[i][j][k]=1;
           //}
            if(a[i][j]>='1'&&a[i][j]<='9')
            {
                int t=a[i][j]-'0';
                 fright[i][j]=t;
            }
        }
       // first.col=0;
        //first.row=0;
        //first.t=0;
        en.col=n-1;
        en.row=m-1;
        en.t=fright[n-1][m-1];
        pre[n-1][m-1].x=-1;
        flag=bfs();
        if(!flag)  cout<<"God please help our poor hero.\n";
        cout<<"FINISH"<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值