hdu1026 Ignatius and the Princess I (bfs)

   


        题目意思就是说, hero 去城堡里救公主; 城堡的规模是n * m 的, 刚开始的时候hero是在(0,0)位置, 要求hero最终到达(n-1, m-1)的最少时间,并输出路径;

 

        输入包含n行m列字符串

             ‘ . ’       表示可以走的地方

             ‘0’ - ‘9’  代表怪物的血量, 杀死怪物需要时间, 怪物有多少血量就要多少时间

             ‘X’        表示墙, 怪物不可以走



             这个题麻烦的是输出路径, 其他的都简单, 也就是一个简单的bfs而已; 这里可以建立一个路径数组来保存路径就可以了;

      这里注意  需要反向扫,  也就是说从 (n-1, m-1)的地方开始扫, 这样, 在当前位置保存上一步位置的值, 放最后输出路径

      的时候就是正向的了

                  



#include<bits/stdc++.h>
using namespace std;

const int maxn = 120;
int vis[maxn][maxn];
int dir[4][2] = {0,-1,0,1,-1,0,1,0};
int n,m;
struct node{                                 //结构体,保存位置和时间
   int x,y,time;
   friend bool operator < (node a, node b)   //排序函数直接写在这里面简单一些
   {
       return a.time > b.time;
   }
};

struct path{   //保存图和路径的结构体      
  int x, y;
  char c;
};

path a[maxn][maxn];   //地图 数组

int bfs()
{
    node now, next;
    priority_queue<node> q; //优先队列,要求最短时间,在这里可以用
    while(q.empty() == 0)   //如果队列为非空, 就拿出来,直到最烈清空
    {
        q.pop();
    }
    now.x = n-1;            //从后向前扫是为了,把上一步的路劲保存到当前位置来,这样正向扫一遍就是正向的路径了
    now.y = m-1;
    if(a[now.x][now.y].c >= '0' && a[now.x][now.y].c <= '9') //如果当前位置有怪物, 就杀掉
    {
        now.time = a[now.x][now.y].c - '0';
    }
    else                      //否则初始时间就为 0
         now.time = 0;
    q.push(now);             //把当前位置压入队列中
    while(q.empty() == 0)    //如果队列为非空
    {
        now = q.top();      //找到队列顶部元素
        q.pop();            //出队
        if(now.x == 0 && now.y ==0)  //如果搜到刚开始的地方 bfs结束, 返回时间
            return now.time;
        for(int i = 0; i < 4; i++)   //四个方向 搜索
        {
            next.x = now.x + dir[i][0];
            next.y = now.y + dir[i][1];
            if(next.x >= 0 && next.x < n && next.y >= 0 && next.y < m && !vis[next.x][next.y] && a[next.x][next.y].c != 'X')
            {
                vis[next.x][next.y] = 1;   //访问数组
                next.time = now.time + 1;  //访问时间
                if(a[next.x][next.y].c >= '0' && a[next.x][next.y].c <= '9')
                {
                    next.time += a[next.x][next.y].c - '0'; //如果有怪物, 要加上杀怪物的时间
                }
                a[next.x][next.y].x = now.x; //保存上一步的路径
                a[next.x][next.y].y = now.y; //保存上一步的路径
                q.push(next);
            }
        }
    }
    return -1;
}

int main()
{
    //freopen("in.txt", "r", stdin);
    while(scanf("%d %d", &n, &m) == 2 && n+m)
    {
        char s[maxn];
        for(int i = 0; i < n; i++)
        {
            scanf("%s", s);
            for(int j = 0; j < m; j++)
            {
                a[i][j].x = i;
                a[i][j].y = j;
                a[i][j].c = s[j];
            }
        }
        memset(vis, 0, sizeof(vis));
        int ans = bfs();
        if(ans == -1)
        {
            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 t = 1;
            int x = 0, y = 0;
            int fx = a[x][y].x, fy = a[x][y].y;
            while(t <= ans)
            {
                fx = a[x][y].x;
                fy = a[x][y].y;
                printf("%ds:(%d,%d)->(%d,%d)\n", t++, x, y, fx, fy);
                if(a[fx][fy].c >= '0' && a[fx][fy].c <= '9')
                    for(int i = 0; i < a[fx][fy].c - '0'; i++)
                     printf("%ds:FIGHT AT (%d,%d)\n",t++, fx, fy);
                x = fx;
                y = fy;
            }
        }
        printf("FINISH\n");
    }
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值