HDOJ 1026 Ignatius and the Princess I

经典BFS+记忆表

 

解题思路:

因为存在具有Hp为n的monster存在,如果直接压入队列,就有可能破坏广度优先树,因此必须在处理的过程中保证monster和‘.’的处理是保存同步的,

处理方法:如果当前位置是monster,那么我就削减他一个HP,再压入队尾,直到HP为0时,把地图上monster的位置置为‘.’可行位置,这样一来,monster

和‘.’的处理就同步了

路径记录:运用到算法导论上的记忆化BFS,具体的操作是建立一个记忆表

  1 #include <queue>
  2 #include <stdio.h>
  3 #include <memory.h>
  4 using namespace std;
  5 
  6 const int maxn = 110;
  7 char maze[maxn][maxn];
  8 int  nNum, mNum, cnt, vis[maxn][maxn];
  9 int  dx[] = {-1, 1, 0, 0};
 10 int  dy[] = {0, 0, -1, 1};
 11 
 12 struct node
 13 {
 14     int x, y, hp, step;
 15 };
 16 
 17 struct parent
 18 {
 19     int px, py, pp;
 20 }prev[maxn][maxn];
 21 
 22 bool IsInBound(int x, int y)
 23 {
 24     if (x<0 || y<0 || x>=nNum || y>=mNum)
 25     {
 26         return false;
 27     }
 28     
 29     return true;
 30 }/* IsInBound */
 31 
 32 void dfs(int x, int y, int pp)
 33 {
 34     if (prev[x][y].px+prev[x][y].py != 0)
 35         dfs(prev[x][y].px, prev[x][y].py, prev[x][y].pp);
 36     
 37     int px = prev[x][y].px;
 38     int py = prev[x][y].py;
 39     
 40     printf("%ds:(%d,%d)->(%d,%d)\n", cnt++, px, py, x, y);
 41     for (int i=1; i<=pp; ++i)
 42         printf("%ds:FIGHT AT (%d,%d)\n", cnt++, x, y);
 43 }/* dfs */
 44 
 45 void bfs()
 46 {
 47     bool IsSolve = false;
 48     queue <node> q;
 49     struct node cur, next;
 50     
 51     cur.x = 0;
 52     cur.y = 0;
 53     cur.step = 0;
 54     cur.hp = 0;
 55     q.push(cur);
 56     
 57     vis[0][0] = 1;
 58     while (!q.empty())
 59     {
 60         cur = q.front();
 61         q.pop();
 62         
 63         if (cur.x==nNum-1 && cur.y==mNum-1
 64             && maze[cur.x][cur.y]=='.')
 65         {
 66             IsSolve = true;
 67             printf("It takes %d seconds to reach the target position, let me show you the way.\n", cur.step);
 68             
 69             cnt = 1;
 70             dfs(cur.x, cur.y, cur.hp);
 71         }/* End of If */
 72         
 73         if (maze[cur.x][cur.y]>='1' && maze[cur.x][cur.y]<='9')
 74         {
 75             int tmp = maze[cur.x][cur.y] - '1';
 76             
 77             if (tmp == 0)
 78                 maze[cur.x][cur.y] = '.';
 79             else
 80                 maze[cur.x][cur.y] = tmp + '0';
 81             
 82             ++cur.step;
 83             q.push(cur);
 84         }/* End of If */
 85         else
 86         {
 87             for (int i=0; i<4; ++i)
 88             {
 89                 next.x = cur.x + dx[i];
 90                 next.y = cur.y + dy[i];
 91                 next.step = cur.step + 1;
 92                 
 93                 if (!vis[next.x][next.y] && IsInBound(next.x, next.y)
 94                     && maze[next.x][next.y]!='X')
 95                 {
 96                     vis[next.x][next.y] = 1;
 97                     prev[next.x][next.y].px = cur.x;
 98                     prev[next.x][next.y].py = cur.y;
 99                     prev[next.x][next.y].pp = cur.hp;
100                     
101                     if (maze[next.x][next.y] == '.')
102                         next.hp = 0;
103                     else
104                         next.hp = maze[next.x][next.y] - '0';
105                     
106                     q.push(next);
107                 }
108             }/* End of For */
109         }/* End of Else */
110     }/* End of While */
111     if (!IsSolve)
112     {
113         printf("God please help our poor hero.\n");
114     }
115 }/* bfs */
116 
117 int main()
118 {
119     while (~scanf("%d %d", &nNum, &mNum))
120     {
121         memset(vis, 0, sizeof(vis));
122         memset(maze, 0, sizeof(maze));
123         memset(prev, 0, sizeof(prev));
124         
125         for (int i=0; i<nNum; ++i)
126             scanf("%s", maze[i]);
127             
128         bfs();
129         printf("FINISH\n");
130     }/* End of While */
131     
132     return 0;
133 }


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值