HDU 1180 (BFS搜索)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1180

题目大意:迷宫中有一堆楼梯,楼梯横竖变化。这些楼梯在奇数时间会变成相反状态,通过楼梯会顺便到达前进方向的下一个点(跳过楼梯)。

同时可以在原地等待,问到达终点的最少时间。

解题思路

很有趣的一个题。

还是先BFS,对于一个楼梯,change函数负责计算出走楼梯能够到达的新的X和Y,再判一次是否越界或不可达。

注意,在‘.‘点是可以原地等待的,需要额外Push这个点,这也是这题不会出现走不出迷宫的数据的原因,否则因为出不去迷宫,会不停在一个点BFS。

然后,程序就爆了。

#include "cstdio"
#include "string"
#include "cstring"
#include "iostream"
#include "queue"
using namespace std;
char map[25][25];
int n,m,sx,sy,ex,ey,dir[4][2]={-1,0,1,0,0,-1,0,1},vis[25][25];
struct status
{
    int x,y,dep;
    status(int x,int y,int dep):x(x),y(y),dep(dep) {}
};
status change(status s,int dir,char c,int dep)
{
    if(dep%2) c=(c==‘|‘?‘-‘:‘|‘);
    if(c==‘|‘)
    {
        if(dir==0) return status(s.x-1,s.y,0);
        if(dir==1) return status(s.x+1,s.y,0);
        if(dir==2||dir==3) return status(-1,-1,0);
    }
    if(c==‘-‘)
    {
        if(dir==0||dir==1) return status(-1,-1,0);
        if(dir==2) return status(s.x,s.y-1,0);
        if(dir==3) return status(s.x,s.y+1,0);
    }
}
int bfs(int x,int y)
{
    queue<status> Q;
    Q.push(status(x,y,0));
    vis[x][y]=true;
    while(!Q.empty())
    {
        status t=Q.front();Q.pop();
        for(int s=0;s<4;s++)
        {
            int X=t.x+dir[s][0],Y=t.y+dir[s][1];
            if(X<1||X>n||Y<1||Y>m||vis[X][Y]||map[X][Y]==‘*‘) continue;
            if(map[X][Y]==‘|‘||map[X][Y]==‘-‘)
            {
                status nw=change(status(X,Y,0),s,map[X][Y],t.dep);
                X=nw.x;Y=nw.y;
            }
            if(X<1||X>n||Y<1||Y>m||vis[X][Y]||map[X][Y]==‘*‘) continue;
            vis[X][Y]=true;
            if(X==ex&&Y==ey) return t.dep+1;
            Q.push(status(X,Y,t.dep+1));
        }
        if(map[t.x][t.y]!=‘|‘||map[t.x][t.y]!=‘-‘) Q.push(status(t.x,t.y,t.dep+1));
    }
    return -1;
}
int main()
{
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    string tt;
    while(cin>>n>>m)
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            cin>>tt;
            for(int j=0;j<tt.size();j++)
            {
                map[i][j+1]=tt[j];
                if(tt[j]==‘S‘) {sx=i;sy=j+1;}
                if(tt[j]==‘T‘) {ex=i;ey=j+1;}
            }
        }
        int ans=bfs(sx,sy);
        cout<<ans<<endl;
    }
}
11891440 2014-10-17 01:13:57 Accepted 1180 15MS 308K 2067 B C++ Physcal
时间: 2024-10-03 14:55:46

HDU 1180 (BFS搜索)的相关文章

HDU 1242 (BFS搜索+优先队列)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1242 题目大意:多个起点到一个终点,普通点耗时1,特殊点耗时2,求到达终点的最少耗时. 解题思路: 如果没有特殊点,就是普通BFS. 由于特殊点的介入,所以对于一个点,可能由不同种方式到达,所以使用优先队列,对于一个点,最先取出的点用的方式肯定是最优的. 同时使用优先队列也为BFS过程提供一个剪枝,因为最先到达肯定是最优结果,只要搜到第一个结果,后面就不用搜了. 注意有多个起点,所以先记录下所有起

HDU 2531 (BFS搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2531 题目大意: 你的身体占据多个点.每次移动全部的点,不能撞到障碍点,问撞到目标点块(多个点)的最少步数. 解题思路: 挺有趣的一个题,每次要移动多个点. 如果只移动一个点,就是个简单粗暴的BFS. 多个点照样处理,读图的时候把扫到的第一个点当作移动点,然后vector记录下身体的其它点与该移动点的相对坐标. BFS的时候,先看看移动点能不能动,然后再根据身体的相对坐标还原出身体的绝对坐标,看看

HDU 1026 (BFS搜索+优先队列+记录方案)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1026 题目大意:最短时间内出迷宫.迷宫里要杀怪,每个怪有一定HP,也就是说要耗一定时.输出方案. 解题思路: 要是没有输出方案,就是一个简单粗暴的BFS. 一开始解决输出方案问题时,简单粗暴地在每次状态里加个vector,然后连带vector一起转移. 结果vector的push_back实在太慢,无论怎么优化都是T. 于是参考了ACMan同学的方案,path[X][Y]记录下父亲点. 最后输出的

HDU 1312 (BFS搜索模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1312 题目大意:问迷宫中有多少个点被访问. 解题思路: DFS肯定能水过去的.这里就拍了一下BFS. 然后发现自己BFS访问标记有问题,导致某些点被重复访问了. 赶紧改了一下. #include "cstdio" #include "queue" #include "string" #include "cstring" #inc

HDU 2612 (BFS搜索+多终点)

题目链接: http://poj.org/problem?id=1947 题目大意:两人选择图中一个kfc约会.问两人到达时间之和的最小值. 解题思路: 对于一个KFC,两人的BFS目标必须一致. 于是就有以下的SB行为:记录所有KFC,对于每个KFC,对两人BFS.然后你就会看见红红的TLE. 实际上,只需要两次BFS就可以了,用time_k[0][i]记录a同学到达第i个kfc的时间,time_k[1][i]记录b同学到达第i个kfc的时间. 在一次bfs过程中,记录到达所有kfc的时间.

hdu 1240:Asteroids!(三维BFS搜索)

Asteroids! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3159    Accepted Submission(s): 2106 Problem Description You're in space.You want to get home.There are asteroids.You don't want to hit

HDU 1180——诡异的楼梯( BFS)

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

HDU 5335 Walk Out(Bfs搜索字典序最小的最短路)

 题意:nXm的地图, 问通过四个方向从(1,1)走到(1000,1000)所经过的最小二进制序列是多少,忽略前缀0. 思路:首先如果起点为0,那么我们bfs搜索和起点0联通的为0的连通块,这样我们第一步肯定是从与这个连通块相邻的且与重点最近的地方出发. 将所有可能起点加入队列,在bfs一遍找到字典序最小的那条路就是答案, 在这里可以用两个vector类型容器,一个是q2存储所有节点值存为0的结点, 另一个q3存储节点值为1的结点. 那么如果q2不为空那么也就是有可以走零,那么就从这里面选,

hdu 1026 Ignatius and the Princess I(bfs搜索+输出路径)

题目来源:hdu-1026 Ignatius and the Princess I Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 14677 Accepted Submission(s): 4653 Special Judge Problem Description The Princ