HDU1026

艰难得A出了这个网上大佬认为得水题,这类题在SDNU见过一次,应该用优先队列来做,因为是以时间优先寻解得,而普通的BFS是以最短路径(贪心)得出解得

但是如何存储我们的路径呢(要求输出路径)并且还要先输出总时间,这就代表,你得先搜完并且得出最优时间,输出时间后,还得一步一步把你存好的路径数出来

正向得输出路径,那就得逆向来搜,用pre存储路径

先来看看准备吧

#include <iostream>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <memory.h>
using namespace std;
int n,m;
struct node{
    int x;
    int y;
    char cc;
    int times;
    friend bool operator <(node a,node b)
    {
        return a.times>b.times;  //重载小于号,使得时间小的先出队列;
    }
}a[105][105],now,nex;
struct Pre{
    int px,py;
}pre[105][105];//记录前驱!
int vis[105][105];
int foot[4][2]= {1,0,-1,0,0,1,0,-1};
priority_queue<node> q;
node a[105][105]主要是想用来存储地图(其实浪费了很多,还可以优化得)

now,nex用于bfs搜索

Pre pre[105][105]用来存储路径,因为是倒着走假如从10走到1,那么pre[10] = -1最后输出结束得判断标志

pre[9] = 10; pre[7] = 9——寻求最优解得情况最后pre[1] = 7;

那么你就能从1(起点)开始利用pre数组把路径输出了,注意特判一下终点得时候,详情看代码中

vis数组和foot数组应该很熟悉,只是可能和你起的名不一样

int main()
{
    while(scanf("%d%d",&n,&m)!= EOF)
    {
        getchar();
        memset(vis,0,sizeof(vis));
        memset(a,0,sizeof(a));
        memset(pre,0,sizeof(pre));
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j <= m;j++)
            {
                scanf("%c",&a[i][j].cc);
            }
            getchar();
        }

        if(!bfs(n,m))
        {
            cout<<"God please help our poor hero.\nFINISH"<<endl;
        }
    }
    return 0;
}
输入也挺有讲究得,一定要注意吃不吃空行得问题!!!!请看两个getchar()分别吃了哪里得空行呢?

然后看BFS前期工作

while(!q.empty())q.pop();
    pre[x][y].px = -1;
    vis[x][y] = 1;
    //cout<<"pre[x][y].px = "<<pre[x][y].px<<endl;
    now.x = x;
    now.y = y;
    if(a[x][y].cc == '.')
    {
        now.times = 0;
    }
    else if(a[x][y].cc == 'X')
    {
        return false;
    }
    else if(a[x][y].cc >= '1' && a[x][y].cc <='9')
    {
        now.times = a[x][y].cc - '0';
    }

    q.push(now);
注意清空队列,防止对下一次得输出产生干扰

事先准备

 pre[x][y].px = -1;vis[x][y] = 1;
最后有了一个特判最后结束得清况,因为一旦跳到了最后得那一个点我的while寻环就结束了,那终点有怪咋办啊,是吧没输出

而且终点得初始时间也得加上(只考虑有没有怪,不同的代码写法初始时间也不同)

while(!q.empty())
    {
        now = q.top();
        q.pop();
        for(int i = 0;i < 4;i++)
        {
            int nextx = now.x + foot[i][0];
            int nexty = now.y + foot[i][1];
            if(nextx >= 1 && nextx <= n && nexty >= 1 && nexty <= m && a[nextx][nexty].cc != 'X' && !vis[nextx][nexty])
            {
                nex.x = nextx;
                nex.y = nexty;
                vis[nextx][nexty] = 1;
                if(a[nextx][nexty].cc == '.')
                {
                    nex.times = now.times + 1;
                }
                if(a[nextx][nexty].cc >= '1' && a[nextx][nexty].cc <= '9')
                {
                    nex.times = now.times + a[nextx][nexty].cc - '0' + 1;
                }
                //cout<<nex.times<<endl;
                pre[nex.x][nex.y].px = now.x;
                pre[nex.x][nex.y].py = now.y;
                //printf("pre[%d][%d].px = %d\n",nex.x,nex.y,now.x);
               // printf("pre[%d][%d].py = %d\n",nex.x,nex.y,now.y);
                q.push(nex);
            }
        }
    }
    return false;
}
我觉得这一部分是挺正常得BFS,就是更替入队出对得gu
if(now.x == 1 && now.y == 1)
        {
            printf("It takes %d seconds to reach the target position, let me show you the way.\n",now.times);
            int qq = now.times;
            int time = 0;
            while(pre[now.x][now.y].px != -1)
            {
                //cout<<now.x<<endl<<now.y<<endl;
                if(a[now.x][now.y].cc == '.')
                {
                    printf("%ds:(%d,%d)->(%d,%d)\n",++time,now.x - 1,now.y - 1,pre[now.x][now.y].px - 1,pre[now.x][now.y].py - 1 );
                }
                else if(a[now.x][now.y].cc >= '1' && a[now.x][now.y].cc <= '9')
                {
                    int fightt = a[now.x][now.y].cc - '0';
                    while(fightt--)
                    {
                        printf("%ds:FIGHT AT (%d,%d)\n",++time,now.x - 1,now.y - 1);
                    }
                    printf("%ds:(%d,%d)->(%d,%d)\n",++time,now.x - 1,now.y - 1 ,pre[now.x][now.y].px - 1,pre[now.x][now.y].py - 1);
                }
                int t = now.x;
                now.x = pre[t][now.y].px;//now.x被你改了!!!!!
                now.y = pre[t][now.y].py;
                if(now.x == x && now.y == y)
                if(a[x][y].cc >= '1' && a[x][y].cc <='9')
                {
                    int tt = a[x][y].cc - '0';
                    while(tt--)
                    {
                         printf("%ds:FIGHT AT (%d,%d)\n",++time,x - 1,y - 1);
                    }
                }
            }
            printf("FINISH\n");
            return true;
        }
这一部分就是输出啦,也就是对你前面存储路径思想得实话吧,我的代码最后有个终点得特判输出
加油吧,自己慢慢的写,即使一晚上才弄懂这个题,也是跟着自己的思路走了一遍,而不是直接以别人得思路为起点dfs走一圈,最后

还不一定走的出来,因为会超时得啊~~~





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值