zoukankan      html  css  js  c++  java
  • hdu1180 优先队列bfs+判断方向

    诡异的楼梯

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
    Total Submission(s): 14267    Accepted Submission(s): 3638


    Problem Description
    Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.
    比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
     
    Input
    测试数据有多组,每组的表述如下:
    第一行有两个数,M和N,接下来是一个M行N列的地图,'*'表示障碍物,'.'表示走廊,'|'或者'-'表示一个楼梯,并且标明了它在一开始时所处的位置:'|'表示的楼梯在最开始是竖直方向,'-'表示的楼梯在一开始是水平方向.地图中还有一个'S'是起点,'T'是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在'.'或'S'和'T'所标记的格子内.
     
    Output
    只有一行,包含一个数T,表示到达目标的最短时间.
    注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
     
    Sample Input
    5 5 **..T **.*. ..|.. .*.*. S....
     
    Sample Output
    7
    这道题第一次没看清题意,不知道楼梯还tm会转= =,结果卡壳了,
    一开始没想到优先队列用的queue,后来发现有特殊情况只好改;
    还有就是判断楼梯方向怎么走;

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    char e[25][25];
    int n,m,T;
    int xa,ya,xb,yb;
    int fx[4][2]={-1,0,1,0,0,-1,0,1};
    int book[25][25];
    struct node
    {
    int x,y,t;
    bool operator<(const node& ch)const{
    return t>ch.t;}
    };
    void walk(int zt,int &dx,int& dy,int i) //zt : 1表示'|',2表示’-‘ 
    {
    if(zt==1){                                              //楼梯此时为竖状时,根据上下分为两种情况,只能是上下因为已经在bfs里处理过,方向上下走的定是上下楼梯,反之亦然
    if(i==0) dx--;
    else dx++;
    }
    else if(zt==2){
    if(i==2) dy--;
    else dy++;
    }
    }
    void bfs()
    {
    node temp,cur;
    priority_queue<node> q;
    temp.x=xa,temp.y=ya,temp.t=0;
    book[xa][ya]=1;
    q.push(temp);
    while(!q.empty()){//cout<<"1";
    temp=q.top(),q.pop();
    for(int i=0;i<4;i++){
    cur=temp;

    int dx=cur.x+fx[i][0];
    int dy=cur.y+fx[i][1];
    if(e[dx][dy]=='|'){
    if(cur.t%2==0){ //台阶状态不变为'|'
    if(i<2) walk(1,dx,dy,i); //走的是上下方向
    else
    cur.t++,walk(2,dx,dy,i); //走的是左右方向,等一秒
    }
    else{
    if(i<2) cur.t++,walk(1,dx,dy,i);
    else walk(2,dx,dy,i);
    }
    }
    else if(e[dx][dy]=='-'){
    if(cur.t%2==0){
    if(i>=2) walk(2,dx,dy,i);
    else cur.t++,walk(1,dx,dy,i);
    }
    else{
    if(i>=2) cur.t++,walk(2,dx,dy,i);
    else walk(1,dx,dy,i);
    }
    }
    cur.t++;
    //cout<<"2";
    if(dx<1||dy<1||dx>n||dy>m||book[dx][dy]||e[dx][dy]=='*') continue;
    book[dx][dy]=1;
    cur.x=dx;
    cur.y=dy;

    if(dx==xb&&dy==yb) {cout<<cur.t<<endl;return;}
    q.push(cur);
    //cout<<dx<<" "<<dy<<endl;
    }
    }
    }

    int main(){
    int i,j;
    while(cin>>n>>m){memset(book,0,sizeof(book));
    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    {
    cin>>e[i][j];
    if(e[i][j]=='S') xa=i,ya=j;
    if(e[i][j]=='T') xb=i,yb=j;
    }

    bfs();
    }
    return 0;
    }

    总结:

    记得把出发点push进队列md,还有就是不要急于更改最新点的变量,因为有些判断操作可能要用到之前的变量! 

     +++:

    还有就是queue写时注意book[dx][dy]保存(dx,dy)到起点的最小距离,注意加条件(if(cur.t>=book[dx][dy]) continue);如果不加‘=’TLE,Because会造成大量的重复解进入导致内存占用过度

  • 相关阅读:
    迭代器和生成器
    New test
    MySQL笔记整理
    Python基础数据类型
    Python基础
    Python入门知识
    Linux / MacOS 下Redis 安装、配置和连接
    NuGet的使用心得
    简单工厂模式和策略模式的区别与结合
    NuGet的使用和服务搭建
  • 原文地址:https://www.cnblogs.com/zzqc/p/6557692.html
Copyright © 2011-2022 走看看