zoukankan      html  css  js  c++  java
  • HDU 1885 Key Task(BFS + 状态压缩)

      做这个题的时候我给想简单了,还以为是个基础的广搜,后来发现搜索无法完成,因为vis的标记已经不能再使用了,因为一旦标记了,同一个结点不能走两次,而题目中有的时候有些点必须要走两次,甚至多次.

    我就无从下手了,赛后看了题解才知道,每个点都有16个状态,用状态压缩可以来保存每个点的钥匙状态,开一个三维的vis数组就可以了,然后这就变成了普通的bfs...代码如下.

      还有就是,在一开始的时候我把状态记录错了,我竟然把|8写成了|16...给我整的一头雾水,后来才发现原来竟然是这里出错了..

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    /// b y r g
    /// 1 2 3 4
    /// 1 2 4 8
    int n,m,vis[110][110][16],go[4][2] = {1,0,-1,0,0,1,0,-1};
    char maps[110][110];
    struct Pos
    {
        int x,y,step,state;
        friend bool operator < (const Pos &a,const Pos &b)
        {
            return a.step > b.step;
        }
    };
    priority_queue<Pos> que;
    Pos st,ex;
    bool OK1(int x,int y)
    {
        if(x>=0&&x<n&&y>=0&&y<m&&maps[x][y]!='#') return true;
        return false;
    }
    bool OK2(int i,int j,int s)
    {
        if(maps[i][j]=='B'&&(s&1))
            return true;
        if(maps[i][j]=='Y'&&(s&2))
            return true;
        if(maps[i][j]=='R'&&(s&4))
            return true;
        if(maps[i][j]=='G'&&(s&8))
            return true;
        return false;
    }
    int bfs(Pos a)
    {
        memset(vis,0,sizeof(vis));
        vis[a.x][a.y][a.state] = 1;
        while(!que.empty()) que.pop();
        que.push(a);
        while(!que.empty())
        {
            Pos now = que.top();
            que.pop();
            Pos nxt;
            for(int k = 0; k < 4; k++)
            {
                int i = now.x + go[k][0];
                int j = now.y + go[k][1];
                if(OK1(i,j))
                {
                    if(OK2(i,j,now.state)&&!vis[i][j][now.state])
                    {
                        vis[i][j][now.state]=1;
                        nxt.step = now.step + 1;
                        nxt.state = now.state;
                        nxt.x = i,nxt.y = j;
                        que.push(nxt);
                    }
                    else if(maps[i][j]=='b'&&!vis[i][j][now.state|1])
                    {
                        vis[i][j][now.state|1] = 1;
                        nxt.step = now.step + 1;
                        nxt.state = now.state|1;
                        nxt.x = i,nxt.y = j;
                        que.push(nxt);
                    }
                    else if(maps[i][j]=='y'&&!vis[i][j][now.state|2])
                    {
                        vis[i][j][now.state|2]=1;
                        nxt.step = now.step + 1;
                        nxt.state = now.state|2;
                        nxt.x = i,nxt.y = j;
                        que.push(nxt);
                    }
                    else if(maps[i][j]=='r'&&!vis[i][j][now.state|4])
                    {
                        vis[i][j][now.state|4]=1;
                        nxt.step = now.step + 1;
                        nxt.state = now.state|4;
                        nxt.x = i,nxt.y = j;
                        que.push(nxt);
                    }
                    else if(maps[i][j]=='g'&&!vis[i][j][now.state|8])
                    {
                        vis[i][j][now.state|8]=1;
                        nxt.step = now.step + 1;
                        nxt.state = now.state|8;
                        nxt.x = i,nxt.y = j;
                        que.push(nxt);
                    }
                    else if(maps[i][j]=='.'&&!vis[i][j][now.state])
                    {
                        vis[i][j][now.state]=1;
                        nxt.step = now.step + 1;
                        nxt.state = now.state;
                        nxt.x = i,nxt.y = j;
                        que.push(nxt);
                    }
                    else if(maps[i][j]=='X')
                        return now.step+1;
                }
            }
        }
        return -1;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            if(n == 0 && m == 0) break;
            for(int i = 0; i < n; i++)
                scanf("%s",maps[i]);
            ex.x = -1;
            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < m; j++)
                {
                    if(maps[i][j] == '*')
                    {
                        st.x = i,st.y = j;
                        st.step = 0,st.state = 0;
                    }
                    if(maps[i][j] == 'X')
                    {
                        ex.x = i,ex.y = j;
                        ex.step = 0,ex.state = 0;
                    }
                }
            }
            if(ex.x == -1)
            {
                puts("The poor student is trapped!");
                continue;
            }
            maps[st.x][st.y] = '.';
            int ans = bfs(st);
            if(ans == -1) puts("The poor student is trapped!");
            else printf("Escape possible in %d steps.
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    linux下好用软件全记录
    Shell之Here Document
    ThinkPHP判断更新是否成功的正确方法
    memcached单点登录配置
    gedit搭建c开发环境
    两种算法的比较,学习算法的重要性
    解决sendmail发送邮件慢的问题
    直接拿来用,10个PHP代码片段(收藏)
    Nginx 简单的负载均衡配置示例
    Nginx 虚拟主机 VirtualHost 配置
  • 原文地址:https://www.cnblogs.com/jifahu/p/5453452.html
Copyright © 2011-2022 走看看