BFS+二进制状态压缩 hdu-1429

好久没写搜索题了,就当练手吧。

vis[][][1025]第三个维度用来维护不同key持有状态的访问情况。

对于只有钥匙没有对应门的位置,置为'.',避免不必要的状态分支。

//
//  main.cpp
//  hdu_1429
//
//  Created by Luke on 16/10/8.
//  Copyright © 2016年 Luke. All rights reserved.
//

#include <iostream>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
int n,m,t;
int ex,ey;
char Map[25][25];
int bit[10];
struct Node
{
    int y,x;
    int key;
    int step;
};
bool vis[25][25][1025];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
bool ok(Node &te)
{
    if(te.step>=t)
        return false;
    if(te.y<0||te.y>=n||te.x<0||te.x>=m)
        return false;
    if(vis[te.y][te.x][te.key])
        return false;
    if(Map[te.y][te.x]=='*')
        return false;
    if(Map[te.y][te.x]>='A'&&Map[te.y][te.x]<='J')
    {
        int fix=bit[Map[te.y][te.x]-'A'];
        if(!(fix&te.key))
            return false;
    }
    if(Map[te.y][te.x]>='a'&&Map[te.y][te.x]<='j')
        te.key|=bit[Map[te.y][te.x]-'a'];
    vis[te.y][te.x][te.key]=1;
    return true;
}
int bfs(int sy,int sx)
{
    queue<Node> q;
    q.push((Node){sy,sx,0,0});
    memset(vis,0,sizeof(vis));
    Node now,nx;
    while(!q.empty())
    {
        now=q.front(),q.pop();
        if(now.y==ey&&now.x==ex)
            return now.step;
        for(int i=0;i<4;i++)
        {
            nx=now;
            nx.y+=dir[i][0],nx.x+=dir[i][1];
            nx.step++;
            if(ok(nx))
                q.push(nx);
        }
    }
    return -1;
}
int main(int argc, const char * argv[]) {
    cin.sync_with_stdio(false);
    bit[0]=1;
    for(int i=1;i<10;i++)
        bit[i]=bit[i-1]<<1;
    while(cin>>n>>m>>t)
    {
        int sx,sy;
        bool fix[10];
        memset(fix,0,sizeof(fix));
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                cin>>Map[i][j];
                if(Map[i][j]>='A'&&Map[i][j]<='J')
                    fix[Map[i][j]-'A']=1;
                if(Map[i][j]=='^')
                    ex=j,ey=i;
                if(Map[i][j]=='@')
                    sx=j,sy=i;
            }
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(Map[i][j]>='a'&&Map[i][j]<='j')
                    if(!fix[Map[i][j]-'a'])
                        Map[i][j]='.';
        cout<<bfs(sy,sx)<<endl;
    }
    return 0;
}

 

posted @ 2016-10-08 21:15  Luke_Ye  阅读(471)  评论(0编辑  收藏  举报