HDU 1026 (BFS搜索+优先队列+记录方案)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1026

题目大意:最短时间内出迷宫。迷宫里要杀怪,每个怪有一定HP,也就是说要耗一定时。输出方案。

解题思路

要是没有输出方案,就是一个简单粗暴的BFS。

一开始解决输出方案问题时,简单粗暴地在每次状态里加个vector,然后连带vector一起转移。

结果vector的push_back实在太慢,无论怎么优化都是T。

于是参考了ACMan同学的方案,path[X][Y]记录下父亲点。

最后输出的时候,要么递归输出,要么就选择从终点BFS, 这样就可以顺序输出。

#include "cstdio"
#include "cstring"
#include "string"
#include "iostream"
#include "queue"
#include "vector"
using namespace std;
#define inf 1<<28
struct status
{
    int x,y,dep;
    status() {}
    status(int x,int y,int dep):x(x),y(y),dep(dep) {}
    bool operator < (const status &a) const
    {
        return dep > a.dep;
    }
};
int n,m,dir[4][2]={-1,0,1,0,0,-1,0,1},map[105][105],spec[105][105],vis[105][105],ans;
status path[105][105];
void bfs(int x,int y)
{
    priority_queue<status> Q;
    Q.push(status(x,y,map[x][y]-1));
    vis[x][y]=true;
    bool flag=false;
    while(!Q.empty())
    {
        if(flag) break;
        status t=Q.top();Q.pop();
        for(int s=0;s<4;s++)
        {
            int X=t.x+dir[s][0],Y=t.y+dir[s][1];
            if(vis[X][Y]||X<0||X>=n||Y<0||Y>=m||!map[X][Y]) continue;
            vis[X][Y]=true;
            path[X][Y].x=t.x;
            path[X][Y].y=t.y;
            Q.push(status(X,Y,t.dep+map[X][Y]));
            if(X==0&&Y==0) {flag=true;ans=min(ans,t.dep+map[X][Y]);break;}
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    string tt;
    while(cin>>n>>m)
    {
        memset(vis,0,sizeof(vis));
        memset(spec,0,sizeof(spec));
        ans=inf;
        for(int i=0; i<n; i++)
        {
            cin>>tt;
            for(int j=0; j<tt.size(); j++)
            {
                if(tt[j]==‘X‘) map[i][j]=0;
                else if(tt[j]==‘.‘) map[i][j]=1;
                else {map[i][j]=tt[j]-‘0‘+1;spec[i][j]=tt[j]-‘0‘;}
            }
        }
        bfs(n-1,m-1);
        if(ans==inf) printf("God please help our poor hero.\n");
        else
        {
            printf("It takes %d seconds to reach the target position, let me show you the way.\n",ans);
            int no=1,x=0,y=0;
            while(no<=ans)
            {
                int fx=path[x][y].x,fy=path[x][y].y;
                if(map[fx][fy]) printf("%ds:(%d,%d)->(%d,%d)\n",no++,x,y,fx,fy);
                for(int i=1;i<=spec[fx][fy];i++) printf("%ds:FIGHT AT (%d,%d)\n",no++,fx,fy);
                x=fx,y=fy;
            }
        }
        printf("FINISH\n");
    }
}
11872162 2014-10-14 19:47:07 Accepted 1026 15MS 552K 2286 B C++ Physcal
时间: 2024-12-10 09:33:37

HDU 1026 (BFS搜索+优先队列+记录方案)的相关文章

HDU 1242 (BFS搜索+优先队列)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1242 题目大意:多个起点到一个终点,普通点耗时1,特殊点耗时2,求到达终点的最少耗时. 解题思路: 如果没有特殊点,就是普通BFS. 由于特殊点的介入,所以对于一个点,可能由不同种方式到达,所以使用优先队列,对于一个点,最先取出的点用的方式肯定是最优的. 同时使用优先队列也为BFS过程提供一个剪枝,因为最先到达肯定是最优结果,只要搜到第一个结果,后面就不用搜了. 注意有多个起点,所以先记录下所有起

HDU 2653 (记忆化BFS搜索+优先队列)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2653 题目大意:迷宫中有普通点和陷阱.其中普通点可以走可以飞,但是陷阱只能飞.走耗时1,飞耗时2.但是飞耗能1.给定一定能量P,问是否能在T秒内走出. 解题思路: 一开始SB似地认为每个点最多访问两次.其实每个点最多可以访问P次. vis[X][Y][P]表示在(x,y)点能量为P的状态. 容易出错的地方在于这个组合: @. ,虽说是飞吧,但是还是会在陷阱上卡1s,尽管下一个点是. ,但是这种情况

hdu 1026 bfs+记录路径

题意:从0,0点出发到n-1,m-1点,路上的数字代表要在这个点额外待多少秒,求最短的路 递归输出路径即可 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9

HDU 1026 bfs与dfs

一般来说,广搜常用于找单一的最短路线,或者是规模小的路径搜索,它的特点是"搜到就是最优解", 而深搜用于找多个解或者是"步数已知(比如3步就必须达到条件)"的问题,它的空间效率高,但是找到的不一定是最优解,必须记录并完成整个搜索,故一般情况下,深搜需要非常高效的剪枝(优化). 像搜索最短路径这些的很明显要是用广搜,因为广搜的特性就是一层一层往下搜的,保证当前搜到的都是最优解,当然,最短路径只是一方面的应用,像什么最少状态转换也是可以应用的.深搜就是优先搜索一棵子树,

HDU 2531 (BFS搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2531 题目大意: 你的身体占据多个点.每次移动全部的点,不能撞到障碍点,问撞到目标点块(多个点)的最少步数. 解题思路: 挺有趣的一个题,每次要移动多个点. 如果只移动一个点,就是个简单粗暴的BFS. 多个点照样处理,读图的时候把扫到的第一个点当作移动点,然后vector记录下身体的其它点与该移动点的相对坐标. BFS的时候,先看看移动点能不能动,然后再根据身体的相对坐标还原出身体的绝对坐标,看看

HDU 1180 (BFS搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1180 题目大意:迷宫中有一堆楼梯,楼梯横竖变化.这些楼梯在奇数时间会变成相反状态,通过楼梯会顺便到达前进方向的下一个点(跳过楼梯). 同时可以在原地等待,问到达终点的最少时间. 解题思路: 很有趣的一个题. 还是先BFS,对于一个楼梯,change函数负责计算出走楼梯能够到达的新的X和Y,再判一次是否越界或不可达. 注意,在'.'点是可以原地等待的,需要额外Push这个点,这也是这题不会出现走不出

HDU 2612 (BFS搜索+多终点)

题目链接: http://poj.org/problem?id=1947 题目大意:两人选择图中一个kfc约会.问两人到达时间之和的最小值. 解题思路: 对于一个KFC,两人的BFS目标必须一致. 于是就有以下的SB行为:记录所有KFC,对于每个KFC,对两人BFS.然后你就会看见红红的TLE. 实际上,只需要两次BFS就可以了,用time_k[0][i]记录a同学到达第i个kfc的时间,time_k[1][i]记录b同学到达第i个kfc的时间. 在一次bfs过程中,记录到达所有kfc的时间.

HDU 1312 (BFS搜索模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1312 题目大意:问迷宫中有多少个点被访问. 解题思路: DFS肯定能水过去的.这里就拍了一下BFS. 然后发现自己BFS访问标记有问题,导致某些点被重复访问了. 赶紧改了一下. #include "cstdio" #include "queue" #include "string" #include "cstring" #inc

hdu 1026 Ignatius and the Princess I (BFS+优先队列)

Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11700    Accepted Submission(s): 3653Special Judge Problem Description The Princess has been abducted by the BEelzebub