hdu 1072 Nightmare

来源:互联网 发布:武汉安天怎么样 知乎 编辑:程序博客网 时间:2024/04/28 08:10

Description

Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb on him. The labyrinth has an exit, Ignatius should get out of the labyrinth before the bomb explodes. The initial exploding time of the bomb is set to 6 minutes. To prevent the bomb from exploding by shake, Ignatius had to move slowly, that is to move from one area to the nearest area(that is, if Ignatius stands on (x,y) now, he could only on (x+1,y), (x-1,y), (x,y+1), or (x,y-1) in the next minute) takes him 1 minute. Some area in the labyrinth contains a Bomb-Reset-Equipment. They could reset the exploding time to 6 minutes.

Given the layout of the labyrinth and Ignatius' start position, please tell Ignatius whether he could get out of the labyrinth, if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1.

Here are some rules:
1. We can assume the labyrinth is a 2 array.
2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.
3. If Ignatius get to the exit when the exploding time turns to 0, he can't get out of the labyrinth.
4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can't use the equipment to reset the bomb.
5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.
6. The time to reset the exploding time can be ignore, in other words, if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6.
 

Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth. Then N lines follow, each line contains M integers. The array indicates the layout of the labyrinth.
There are five integers which indicate the different type of area in the labyrinth:
0: The area is a wall, Ignatius should not walk on it.
1: The area contains nothing, Ignatius can walk on it.
2: Ignatius' start position, Ignatius starts his escape from this position.
3: The exit of the labyrinth, Ignatius' target position.
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.
 

Output

For each test case, if Ignatius can get out of the labyrinth, you should output the minimum time he needs, else you should just output -1.
 

Sample Input

33 32 1 11 1 01 1 34 82 1 1 0 1 1 1 01 0 4 1 1 0 4 11 0 0 0 0 0 0 11 1 1 4 1 1 1 35 81 2 1 1 1 1 1 4 1 0 0 0 1 0 0 1 1 4 1 0 1 1 0 1 1 0 0 0 0 3 0 1 1 1 4 1 1 1 1 1
 

Sample Output

4-113
 
bfs
#include<stdio.h>#include<queue>#include<string.h>#include<iostream>using namespace std;typedef struct nn{    int x,y,time,step;}node;int sx,sy,dx,dy,h,w,map[10][10],Step,vist[10][10];int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};queue<node> QQ;//用来装调时器的,下面看就会懂了void BFS(){    queue<node> Q;    node q,p;    int e,tx,ty;    if(sx==dx&&sy==dy)//首先判断    {        Step=0;return ;    }    q.step=0;q.time=6;q.x=sx;q.y=sy;    vist[sy][sx]=1;     //表示走过    Q.push(q);    while(!Q.empty())    {        q=Q.front();        Q.pop();        if(q.time>1)        for(e=0;e<4;e++)        {            tx=q.x+dir[e][0]; ty=q.y+dir[e][1];            if(tx>=0&&tx<w&&ty>=0&&ty<h&&map[ty][tx]!=0&&!vist[ty][tx])            {                p.step=q.step+1; p.time=q.time-1;                p.x=tx; p.y=ty;                vist[ty][tx]=1;                if(tx==dx&&ty==dy)//找到                {                    Step=p.step;return ;                }                if(map[ty][tx]==4)//当为调时器时,先暂时不走这路线,放入QQ队列,                {                    p.time=6;  //当时时间设成6                    QQ.push(p);                    continue ;                }                Q.push(p);            }        }    }}int main(){    int t,x,y,e,tx,ty;    node q,p;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&h,&w);        for(y=0;y<h;y++)        for(x=0;x<w;x++)        {            scanf("%d",&map[y][x]);            if(map[y][x]==2)            {                sx=x;sy=y;            }            if(map[y][x]==3)            {                dx=x;dy=y;            }        }        memset(vist,0,sizeof(vist));        Step=-1;        BFS();        if(Step==-1)//当上一个找不到时        {            memset(vist,0,sizeof(vist));        while(!QQ.empty())//开始走没有走过的路线        {            q=QQ.front();            QQ.pop();            if(q.time>1)            for(e=0;e<4;e++)            {                tx=q.x+dir[e][0]; ty=q.y+dir[e][1];                if(tx>=0&&tx<w&&ty>=0&&ty<h&&map[ty][tx]!=0&&!vist[ty][tx])                {                    p.step=q.step+1; p.time=q.time-1;                    p.x=tx; p.y=ty;                    vist[ty][tx]=1;                    if(tx==dx&&ty==dy)                    {                        Step=p.step; break ;                    }                    if(map[ty][tx]==4)//为4时,又把当前位置设成6                        p.time=6;                    QQ.push(p);                }            }            if(Step!=-1)//找到了,跳出            break;        }        }        printf("%d\n",Step);    }}

dfs但是我没看明白为什么会最短
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <climits>const int MAX = 9;int dir[4][2]={1,0,-1,0,0,1,0,-1};int map[MAX][MAX],step[MAX][MAX],time[MAX][MAX];int n,m,sx,sy,dx,dy,minx;void dfs(int x,int y,int len,int cnt){if(x<0 || y<0 || x>=n || y>=m)return;if(len<=0 || cnt>=minx)return;if(map[x][y]==0)return;if(map[x][y]==3){if(cnt<minx)minx=cnt;return;}if(map[x][y]==4){len=6;}//下面的这个剪枝很重要,不剪就会超时//从当前点x,y走到下一个可能点的距离大于从其他途径到tx,ty的距离,且到tx,ty点时的剩余时间大于由x,y点到tx,ty点后的剩余时间,就跳过//这是因为结点可重复访问所以本身没标记,那么当上述条件满足时,由tx,ty开始的最优解已经求过(存在或者不存在),所以不需要再重复求了。if(cnt>=step[x][y] && time[x][y]>=len)return;step[x][y]=cnt;time[x][y]=len;int tx,ty,i;for(i=0;i<4;++i){tx = x+dir[i][0];ty = y+dir[i][1];dfs(tx,ty,len-1,cnt+1);}}int main(){//freopen("in.txt","r",stdin);int t,i,j,len,cnt;scanf("%d",&t);while(t--){scanf("%d %d",&n,&m);for(i=0;i<n;++i){for(j=0;j<m;++j){time[i][j]=0;step[i][j]=INT_MAX-3;//这里置一个大数,表示到i,j的步数无限大scanf("%d",&map[i][j]);if(map[i][j]==2){sx = i;sy = j;}else if(map[i][j]==3){dx = i;dy = j;}}}len = 6;cnt = 0;minx = INT_MAX;dfs(sx,sy,len,cnt);if(minx==INT_MAX){printf("-1\n");}else{printf("%d\n",minx);}}    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝发高烧怎么办能快速退烧 屁股上长了纹路怎么办 手机充电头歪了怎么办 屁股挠烂了化脓怎么办 手机充电那坏了怎么办 孩子在学校被老师冤枉怎么办 初中学校不好我该怎么办 天气太热屁股淹了怎么办 骑车骑的屁股疼怎么办 爬山时屁股摔紫青了怎么办 宝宝不肯脱裤子拉粑粑怎么办 国家对无地农民怎么办 生完孩子骨架变大怎么办 17岁长高很慢怎么办? 出月子腿着凉了怎么办 脚着凉了脚疼怎么办 腿着凉了特别疼怎么办 孩子骨龄大2两年怎么办 和人吃饭很尴尬怎么办 头不自觉向右偏怎么办 靠墙站立腰疼怎么办 小腿酸痛乏力肌肉萎缩怎么办 搬重物后手臂疼怎么办 和尚鹦鹉吃了盐怎么办 刚买鹦鹉不上手怎么办 word的文件时间改了怎么办 图强gps编码丢失怎么办 武统台湾后岛民怎么办 没有你我怎么办是什么歌 ios 12软件闪退怎么办 来大姨妈想吐怎么办 3岁宝宝体重轻怎么办 硕士延期毕业考上博士怎么办 中国人移民欧洲饮食不习惯怎么办 出车祸了报警警察不管怎么办 高中的孩子不好好上学怎么办 和老公消费观念不合拍怎么办 去医院没带现金怎么办 微信读书下架了怎么办 24岁血压有点高怎么办 吃鸡鼠标弹出来怎么办