码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2128 Tempter of the Bone II

时间:2015-03-15 09:33:42      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:bfs   acm算法   地图   搜索   amp   

Tempter of the Bone II

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 98304/32768 K (Java/Others)
Total Submission(s): 1638    Accepted Submission(s): 435


Problem Description
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze was changed and the way he came in was lost.He realized that the bone was a trap, and he tried desperately to get out of this maze.


The maze was a rectangle with the sizes of N by M. The maze is made up of a door,many walls and many explosives. Doggie need to reach the door to escape from the tempter. In every second, he could move one block to one of the upper, lower, left or right neighboring blocks. And if the destination is a wall, Doggie need another second explode and a explosive to explode it if he had some explosives. Once he entered a block with explosives,he can take away all of the explosives. Can the poor doggie survive? Please help him.
 


Input
The input consists of multiple test cases. The first line of each test case contains two integers N, M,(2 <= N, M <= 8). which denote the sizes of the maze.The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

‘X‘: a block of wall;
‘S‘: the start point of the doggie;
‘D‘: the Door;
‘.‘: an empty block;
‘1‘--‘9‘:explosives in that block.

Note,initially he had no explosives.

The input is terminated with two 0‘s. This test case is not to be processed.
 


Output
For each test case, print the minimum time the doggie need to escape if the doggie can survive, or -1 otherwise.
 


Sample Input
4 4 SX.. XX.. .... 1..D 4 4 S.X1 .... ..XX ..XD 0 0
 


Sample Output
-1 9
 


Author
XHD
 


Source


一道比较恶心的BFS题目。
题意:从S点出发,到D点。X是墙不可走。数字1到9代表炸弹。可以炸墙。炸墙的时间为一秒。
问是否能逃出去,能的话输出最短时间。不能的话输出-1.
解题思路:优先队列+bfs。。
因为走过的点可以再走,所以不能简单的用二维数组来标记,用三个三维数组就好了。然后设定一个值(我定为50),这个值代表经过某一点N次。
三维数组的话,第一维,第二维是坐标。第三维是炸弹数。整个三维数组代表拥有几个炸弹数在某一点的情况,搜的条件是越界排除,经过某一点小于50次(即不重复走这个点50次),因为数据很小,根本不可能走同一点50次。
搜的时候只有三种情况。
因为图是变的,存图的话用个结构体存。
做好这些之后就是非常清晰直观的bfs+优先队列了。
上个代码。
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
struct node
{
    int x,y,num,step;
    char mp[15][15];
    bool friend operator<(node a,node b)
    {
        return a.step>b.step;
    }
} t;
int dir[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
char s[15][15];
int vis[15][15][55];
int n,m,ex,ey,flag;
int bfs(int x,int y)
{
    priority_queue<node>q;
    int i,j;
    for(i=0; i<n; i++)
        for(j=0; j<m; j++)
            t.mp[i][j]=s[i][j];
    t.step=0;
    t.num=0;
    t.x=x;
    t.y=y;
    vis[t.x][t.y][0]++;
    q.push(t);
    while(!q.empty())
    {
        t=q.top();
        if(t.x==ex && t.y==ey)
            return t.step;
        for(i=0; i<4; i++)
        {
            t.step++;
            t.x+=dir[i][1];
            t.y+=dir[i][0];
            //下面三种情况。
            if(t.x>=0 && t.x<n && t.y>=0 && t.y<m && vis[t.x][t.y][t.num]<50)
            {
                if(t.mp[t.x][t.y]=='.')
                {
                    vis[t.x][t.y][t.num]++;
                    q.push(t);
                }
                else if(t.mp[t.x][t.y]=='X' && t.num>0) //有炸弹碰到墙才炸。
                {
                    vis[t.x][t.y][t.num]++;
                    t.step++;
                    t.num--;
                    t.mp[t.x][t.y]='.';
                    q.push(t);
                }
                else if(t.mp[t.x][t.y]>='1' && t.mp[t.x][t.y]<='9')
                {
                    vis[t.x][t.y][t.num]++;
                    t.num+=t.mp[t.x][t.y]-'0';
                    t.mp[t.x][t.y]='.';
                    q.push(t);
                }
            }
            t=q.top();
        }
        q.pop();
    }
    return -1;
}
int main()
{
    int i,j,x1,y1;
    while(~scanf("%d%d",&n,&m) && n)
    {
        for(i=0; i<n; i++)
            scanf("%s",s[i]);
        for(i=0; i<n; i++)
            for(j=0; j<m; j++)
            {
                if(s[i][j]=='S')
                {
                    s[i][j]='.';
                    x1=i,y1=j;
                }
                else if(s[i][j]=='D')
                {
                    s[i][j]='.';
                    ex=i,ey=j;
                }
            }
        memset(vis,0,sizeof vis);
        printf("%d\n",bfs(x1,y1));
    }
}



HDU 2128 Tempter of the Bone II

标签:bfs   acm算法   地图   搜索   amp   

原文地址:http://blog.csdn.net/sky_miange/article/details/44263115

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!