zoukankan      html  css  js  c++  java
  • [HDU] 1180 诡异的楼梯个人觉得比较有趣的广搜索

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1180

    方法:此题和一般的地图广搜差不多,唯一的变化就是在楼梯那里,楼梯那里考虑的方式如下:

    1.根据楼梯的初始状态和当时达到楼梯旁边的位置时走的时间来确定这个时候楼梯的方向。

    2.再根据当时前进的方向 和 当时楼梯的方向确定走过去要多少的时间,是用1还是2.

    3.不管走过去后时间是多少,如果过去后发现是障碍物或已经去过了,则该位置不进队列,不考虑从该位置开始的一个广搜。

    4.如果可以从楼梯过去的那个位置进行广搜,那么该位置开始广受的广搜索不能再经过刚才才经过的楼梯,要判断这个信息不能简单通过设置visited变量,因为很多路径都有可能经过该楼梯。本代码中用一个4维数组来标记到达每一个位置有没有刚走过什么楼梯。laddUserd[x][y][u][w] =true 表示到达(x ,y)的最短路径刚经过了 (u,w)处的电梯,所以在(x,y)如果探寻到了楼梯,可以一下就判断出是不是刚走过这段楼梯,这样避免无谓的搜索。

    感想:简单有趣的广搜。

    代码:

    View Code
    #include <iostream>
    #include <queue>
    using namespace std;
    int m,n;
    char map[22][22];
    char obstacle ='*';
    char road = '.';
    char v_ladder='|';
    char h_ladder='-';
    char start ='S';
    char target='T';
    bool visited[22][22];
    int deriction[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
    struct status
    {
        int x;
        int y;
        int currentTime;
    };
    struct cmp
    {
        bool operator()(status x,status y)
        {
            if(x.currentTime > y.currentTime)
                return true;
            return false;
        }
    };
    bool canGo(int x,int y)
    {
        return !visited[x][y] && map[x][y]!=obstacle;
    }
    bool laddUsed[21][21][21][21];
    void BFSSearch(int x,int y)
    {
        priority_queue<status,vector<status>,cmp> q;
        status st_status;
        st_status.x=x;
        st_status.y=y;
        st_status.currentTime=0;
        q.push(st_status);
        while(!q.empty())
        {
            status t_status = q.top();
            q.pop();
            if(!visited[t_status.x][t_status.y])
            {
                visited[t_status.x][t_status.y] = true;
                if(map[t_status.x][t_status.y]==target)
                {
                    cout<<t_status.currentTime<<endl;
                    break;
                }
                int n_x,n_y;
                for(int i =0;i<4;i++)
                {
                    n_x = t_status.x+deriction[i][0];
                    n_y = t_status.y+deriction[i][1];
                    if(canGo(n_x,n_y))
                    {
                        status n_status;
                        n_status.x=n_x;
                        n_status.y=n_y;
                        n_status.currentTime = t_status.currentTime;
                        if(map[n_x][n_y] == road || map[n_x][n_y] == target)
                        {
                            n_status.currentTime ++;
                            q.push(n_status);
                        }
                        else if(!laddUsed[t_status.x][t_status.y][n_x][n_y])
                        {
                            if(i==1 || i==3)//vertical orientation
                            {
                                if(map[n_x][n_y]==v_ladder)
                                    n_status.currentTime +=  n_status.currentTime%2 == 0 ? 1:2;
                                else if(map[n_x][n_y]==h_ladder)
                                    n_status.currentTime +=  n_status.currentTime%2 == 1 ? 1:2;
                                if(canGo(n_x+deriction[i][0],n_y))
                                {
                                        n_status.x+=deriction[i][0];
                                        q.push(n_status);
                                        laddUsed[n_status.x][n_status.y][n_x][n_y]=true;
                                }
                            }
                            else if(i==0 || i==2)//horizontal orientation
                            {
                                if(map[n_x][n_y]==h_ladder)
                                    n_status.currentTime +=  n_status.currentTime%2 == 0 ? 1:2;
                                else if(map[n_x][n_y]==v_ladder)
                                    n_status.currentTime +=  n_status.currentTime%2 == 1 ? 1:2;
                                if(canGo(n_x,n_y+deriction[i][1]))
                                {
                                        n_status.y+=deriction[i][1];
                                        q.push(n_status);
                                        laddUsed[n_status.x][n_status.y][n_x][n_y]=true;
                                }
                            }
                        }
                         
                    }
                }
            }
        }
    }
    void main()
    {
        int startX,startY;
        while(scanf("%d %d",&m,&n) != EOF)
        {
            if(m!=0 && n!=0)
            {
                memset(map,obstacle,sizeof(map));    
                memset(visited,false,sizeof(visited));    
                memset(laddUsed,false,sizeof(laddUsed));
                for(int i=1;i<=m;i++)
                 for(int j=1;j<=n;j++)
                 {
                     cin>>map[i][j];
                     if(map[i][j]==start)
                     {
                         startX = i;
                         startY = j;
                     }
                 }
            BFSSearch(startX,startY);
            }
        }
    }
    
     
  • 相关阅读:
    API
    Object constructor
    function()
    For语句的衍生对象
    编程语言发展史
    将Paul替换成Ringo
    Document.write和 getElementById(ID)
    姓名,电话号码,邮箱的正则检测
    JavaScript-BOM与DOM
    管理心得
  • 原文地址:https://www.cnblogs.com/kbyd/p/3024369.html
Copyright © 2011-2022 走看看