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");
    }
}

 

118721622014-10-14 19:47:07Accepted102615MS552K2286 BC++Physcal
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值