hdu 1072 广搜

广搜,用到优先队列,跟hdu1026差不多。但须注意几个问题:

1、可以往回走,由于可以重设时间,有时需要拐弯去“加油”,但可重设时间的结点不能在让它有机会被重走,不然就进入死循环了。

2、队列每次弹出的都是用时最少的,需要自定义排序

#include <iostream>
#include <queue>
using namespace std;

int map[9][9];
int n,m;
int dir[4][2]={0,1, 1,0, -1,0, 0,-1};

struct Node{
    int x,y;
    int time;
    int step;//剩余的步数
    bool operator<(const Node &a) const{
        return a.time<time;
    }
};

int bfs(int x, int y, int end_x, int end_y)
{
    priority_queue<Node>que;
    struct Node start;
    start.x=x;
    start.y=y;
    start.time=0;
    start.step=6;
    que.push(start);

    while(!que.empty())
    {
        struct Node cur=que.top();
        que.pop();
        if(cur.step==0) continue;//时间到了,结束搜索
        if(cur.step>=1 && cur.x==end_x && cur.y==end_y) return cur.time;//注意要保证剩余时间大于1
        for(int i=0; i<4; i++){
            int xtmp=cur.x+dir[i][0];
            int ytmp=cur.y+dir[i][1];
            if(map[xtmp][ytmp]==0 || xtmp<0 || xtmp>=n || ytmp<0 ||ytmp>=m) continue;
            struct Node next;
            next.x=xtmp;
            next.y=ytmp;
            next.time=cur.time+1;
            next.step=cur.step-1;
            if(map[xtmp][ytmp]==4 && next.step>=1){//注意重设时间的条件                        next.step=6;
                map[xtmp][ytmp]=0;
            }
            que.push(next);
        }
    }
    return -1;
}
int main()
{
    int t, i,j, start_x, start_y, end_x, end_y;
    cin>>t;
    while(t--)
    {
        scanf("%d%d", &n, &m);
        for(i=0; i<n; i++){
            for(j=0; j<m; j++){
                scanf("%d", &map[i][j]);
                if(map[i][j]==2){
                    start_x=i;
                    start_y=j;
                } else if(map[i][j]==3){
                    end_x=i;
                    end_y=j;
                }
            }
        }
        int result=bfs(start_x, start_y, end_x, end_y);
        cout<<result<<endl;
    }
    return 0;
}

一直都是无题解不AC,这次由于做完hdu 1026没多久,很快想到解决的办法,但是在细节处理上还是用了很长的时间。加油!

时间: 2024-10-10 23:08:28

hdu 1072 广搜的相关文章

hdu 1180(广搜好题)

诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 12487    Accepted Submission(s): 3120 Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比 如下面的例子里,一开始楼梯在

HDU 1253 (简单三维广搜) 胜利大逃亡

奇葩!这么简单的广搜居然爆内存了,而且一直爆,一直爆,Orz 而且我也优化过了的啊,尼玛还是一直爆! 先把代码贴上睡觉去了,明天再来弄 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <cmath> 7 using namespace std; 8 9 struct Poin

HDU 1240 (简单三维广搜) Asteroids!

给出一个三维的迷宫以及起点和终点,求能否到大终点,若果能输出最短步数 三维的问题无非就是变成了6个搜索方向 最后强调一下xyz的顺序,从输入数据来看,读入的顺序是map[z][x][y] 总之,这是很基础的一道题 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <algorithm

HDU 3085 Nightmare Ⅱ (双向广搜)

题意:有M,G两人和鬼魂(Z)在n*m的方格内,M每秒走3步,G每秒走一步,鬼魂每秒走2步,问是否能 不遇到鬼魂下两人相遇,鬼魂可以穿墙(X),人不可以.初始鬼魂有2个. #include<stdio.h> #include<string.h> #include<string> #include<queue> #include<map> #include<iostream> #include<algorithm> #def

HDU 1195 Open the Lock (双向广搜)

题意:给你初始4个数字和目标4个数字,问是否能由初始经过变换到目标数字: 变换规则:每个数字可以加1(9+1=1)或减1(1-1=9),或交换相邻的数字(最左和最右不是相邻的). 双向广搜:分别对初始和目标数字进行广搜,vis数组用1和2标记两种已搜索的数字,用mp数组记录状态的步数. 当从前往后搜可以到达2或从后往前搜可以到达1状态则就可以了... #include<stdio.h> #include<string.h> #include<string> #inclu

HDU 1401 Solitaire (双向广搜)

题意:在二维8*8的方格,给定4个初始点和4个最终点,问在8步内是否能从初始点走到最终点, 规则:每个点能上下左右移动,若4个方向已经有点则可以跳到下一个点. 双向广搜:同时对初始点和最终点广搜4步,对每一步记录状态,初始点为'1',最终点为'2', 若在限定时间内初始点的状态能到达'2',或最终点的状态能到达'1',则为YES!要记得排序.. #include<stdio.h> #include<string.h> #include<queue> #include&l

hdu 1242:Rescue(BFS广搜 + 优先队列)

Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 14   Accepted Submission(s) : 7 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Angel was caught by the MOLIGPY

HDU 4771 Stealing Harry Potter&#39;s Precious (深搜+广搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题面: 欢迎参加--BestCoder周年纪念赛(高质量题目+多重奖励) Stealing Harry Potter's Precious Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2207    Accepted Submis

HDU 1026 Ignatius and the Princess I 迷宫广搜剪枝问题

本题是个经典的迷宫广搜问题类型了.网上看到好多解法. 很多解题报告都没什么分析,更不会指出其中的关键点.代码更加像一大抄.有人分析也一大篇分析,不过全部都不切中关键,甚至在分析什么广搜和深搜区别,广搜为什么快之类的,还有喊什么暴搜之类的,全错了.估计这些代码都是抄过的. 通过一大段的时间研究,终于搞通了. 本题虽然可以说是广搜,但是其中的关键却是剪枝法,为什么呢? 因为迷宫并不能简单地广搜就能搜索出所有路径的,甚至只要迷宫大点就不能搜索出是否有路径,如果没有条件剪枝的情况下:不信,你严格写一个广