zoukankan      html  css  js  c++  java
  • HDU 5025 (BFS+记忆化状压搜索)

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

    题目大意: 迷宫中孙悟空救唐僧,可以走回头路。必须收集完钥匙,且必须按顺序收集。迷宫中还有蛇,杀蛇多耗时1,蛇杀完就没了。问最少耗时。

    解题思路

    2014广州网赛的水题之一。当时没刷过BFS状压,结果悲剧了。

    由于钥匙强制有序,所有得压蛇。

    设f[x][y][key][snake]为在(x,y)点,已经取得的钥匙key,以及杀蛇snake的状态。

    对于钥匙k,如果k==key+1,那么 key++

    对于蛇k,如果!snake&(1<<k)那么dep++

    其他情况则dep++即可

    由于杀蛇导致BFS树同层分布不均衡,可以使用优先队列来优化。不过维护优先队列需要时间,可能效果适得其反orz。

     

    #include "cstdio"
    #include "string"
    #include "cstring"
    #include "iostream"
    #include "queue"
    using namespace std;
    struct status
    {
        int x,y,dep,key,snake;
        status(int x,int y,int dep,int key,int snake):x(x),y(y),dep(dep),key(key),snake(snake) {}
        bool operator < (const status &a) const {return dep > a.dep;}
    };
    char map[105][105];
    int n,m,sx,sy,ex,ey,f[105][105][10][35],dir[4][2]={-1,0,1,0,0,-1,0,1},ans;
    void bfs(int x,int y)
    {
        priority_queue<status> Q;
        Q.push(status(x,y,0,0,0)) ;
        f[x][y][0][0]=1;
        bool flag=false;
        while(!Q.empty())
        {
            if(flag) break;
            status t=Q.top();Q.pop();
            for(int s=0;s<4;s++)
            {
                int X=t.x+dir[s][0],Y=t.y+dir[s][1],key=t.key,snake=t.snake,dep=t.dep;
                if(X<1||X>n||Y<1||Y>n||map[X][Y]=='#') continue;
                if(isdigit(map[X][Y]))
                {
                    int k=map[X][Y]-'0';
                    if(k==t.key+1) key++;
                }
                if(islower(map[X][Y]))
                {
                    int k=map[X][Y]-'a';
                    if(!(snake&(1<<k))) {snake=snake|(1<<k);dep++;}
                }
                dep++;
                if(f[X][Y][key][snake]) continue;
                f[X][Y][key][snake]=1;
                if(X==ex&&Y==ey&&key==m) {flag=true;ans=min(ans,dep);}
                Q.push(status(X,Y,dep,key,snake));
            }
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        ios::sync_with_stdio(false);
        string tt;
        while(cin>>n>>m&&n)
        {
            int snake_cnt='a';
            memset(f,0,sizeof(f));
            ans=1<<28;
            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]=='K') {sx=i;sy=j+1;}
                    if(tt[j]=='T') {ex=i;ey=j+1;}
                    if(tt[j]=='S') map[i][j+1]=snake_cnt++;
                }
            }
            bfs(sx,sy);
            if(ans==1<<28) cout<<"impossible"<<endl;
            else cout<<ans<<endl;
        }
    }
    11878237 2014-10-15 16:46:24 Accepted 5025 812MS 15480K 2076 B C++ Physcal
  • 相关阅读:
    mojo 接口示例
    MojoliciousLite: 实时的web框架 概述
    接口返回json
    centos 6.7 perl 版本 This is perl 5, version 22 安装DBI DBD
    centos 6.7 perl 5.22 安装DBD 需要使用老的perl版本
    商业智能改变汽车行业
    商业智能改变汽车行业
    读MBA经历回顾(上)目的决定手段——北漂18年(48)
    perl 升级到5.20版本
    Group Commit of Binary Log
  • 原文地址:https://www.cnblogs.com/neopenx/p/4026803.html
Copyright © 2011-2022 走看看