您的位置:首页 > 其它

hdu 1885 Key Task

2015-08-10 15:11 302 查看
题目链接:

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

解题思路:

状态压缩,使用二进制分别存储每把钥匙是否拥有的状态,然后当遇到门时,查看此时相应的二进制位数上是否有相应的钥匙,如果有,则进队列,继续搜就行了。直到找到终点为止。。。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

struct node{
    int x,y,t;
    int key;//用二进制存4把钥匙  
};
const int dx[] = {-1,0,1,0}, dy[] = {0,-1,0,1};
const char key[] = {'b','y','r','g'};
const char door[] = {'B','Y','R','G'};
char maze[110][110];
int vis[110][110][20];//判断在有不同的key的各个位置是否出现过  
int n,m;

void bfs(int x,int y){
    memset(vis,0,sizeof(vis));
    queue<node> q;
    node cur;
    cur.x = x;cur.y = y;cur.t = 0;cur.key = 0;
    q.push(cur);
    vis[cur.x][cur.y][cur.key] = 1;
    while(!q.empty()){
        cur = q.front();
        q.pop();
        if(maze[cur.x][cur.y] == 'X'){
            printf("Escape possible in %d steps.\n",cur.t);
            return;
        }
        //printf("\n%d %d %d %d\n",cur.x,cur.y,cur.t,cur.key);
        node tmp;
        for(int i = 0; i < 4; i++){
            //cout<<cur.key<<endl;
            tmp.x = cur.x+dx[i];tmp.y = cur.y+dy[i];tmp.t = cur.t+1;tmp.key = cur.key;
            //printf("%d %d %d %d\n",tmp.x,tmp.y,tmp.t,tmp.key);
            if(tmp.x<0 || tmp.x>=n || tmp.y<0 || tmp.y>=m || maze[tmp.x][tmp.y] == '#')
                continue;
            if(islower(maze[tmp.x][tmp.y])){
                for(int j = 0; j < 4; j++){
                    if(maze[tmp.x][tmp.y] == key[j]){
                        //printf("%d %d %d %d11\n",tmp.x,tmp.y,tmp.t,tmp.key);
                        tmp.key |= (1<<j);
                        if(!vis[tmp.x][tmp.y][tmp.key]){
                            //key记录得到这把钥匙 
                            vis[tmp.x][tmp.y][tmp.key] = 1;
                            q.push(tmp);
                        }
                        break;
                    }
                }
            }
            else if(isupper(maze[tmp.x][tmp.y]) && maze[tmp.x][tmp.y] != 'X'){
                //找到对应的门,且有该门的钥匙,且在这种状态下的这个位置未走过 
                for(int j = 0; j < 4; j++){
                    if(maze[tmp.x][tmp.y] == door[j] && (tmp.key & (1<<j)) && !vis[tmp.x][tmp.y][tmp.key]){
                        vis[tmp.x][tmp.y][tmp.key] = 1;
                        q.push(tmp);
                        break;
                    }
                }
            }
            else if(!vis[tmp.x][tmp.y][tmp.key]){
                vis[tmp.x][tmp.y][tmp.key] = 1;
                q.push(tmp);
            }
        }
    }
    printf("The poor student is trapped!\n");
}

int main(){
    while(scanf("%d%d",&n,&m),n+m){
        for(int i = 0; i < n; i++)
            scanf("%s",maze[i]);
        for(int i = 0;i < n; i++)
            for(int j = 0;j < m; j++){
                if(maze[i][j] == '*'){
                    bfs(i,j);
                    break;
                }
            }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: