hdu~1885(bfs+状态压缩)

来源:互联网 发布:网络大电影2016排行榜 编辑:程序博客网 时间:2024/05/17 02:11

Key Task

一开始用dfs果断超时,贴上超时代码:

<span style="font-size:18px;">#include <stdio.h>#include <iostream>#include <string.h>#define MAX 0xffffffint m,n,flag,tt,sx,sy;char key[]={'y','g','r','b'};char door[]={'Y','G','R','B'};int dirx[]={0,1,0,-1},diry[]={1,0,-1,0};char maze[105][105];bool mark[105][105][22];void dfs(int x,int y,int t,int k){    if(flag)        return ;    if(maze[x][y]=='X')    {        tt=t;        flag=1;        return ;    }    if(x<0 || x>=n || y<0 || y>=m ||  maze[x][y]=='#' || mark[x][y][k])        return ;    if(isupper(maze[x][y]) && maze[x][y]!='X')     //це    {        for(int i=0;i<=4;i++)            if(maze[x][y]==door[i])            {                if((k&(1<<i))==0)                    return ;            }    }    else if(islower(maze[x][y]))    //т©Ёв    {        for(int i=0;i<=4;i++)            if(maze[x][y]==key[i])            {                k|=(1<<i);                break;            }    }    for(int i=0;i<4;i++)    {        int fx=x+dirx[i];        int fy=y+diry[i];        mark[x][y][k]=true;        dfs(fx,fy,t+1,k);        mark[x][y][k]=false;    }}int main(){    while(scanf("%d %d",&n,&m) &&(m || n))    {        memset(mark,0,sizeof(mark));        flag=0;        tt=-1;        for(int i=0;i<n;i++)        {            scanf("%s",maze[i]);            for(int j=0;j<m;j++)                if(maze[i][j]=='*')                    sx=i,sy=j;        }        dfs(sx,sy,0,0);        if(tt!=-1)            printf("Escape possible in %d steps.\n",tt);        else            printf("The poor student is trapped!\n");    }    return 0;}</span>


bfs+状态压缩

这题和普通的迷宫不一样的是多了4种钥匙以及对应的门

开一个三维数组mark[x][y][k]用来存各个位置的各种状态,通俗的说就是,判断在"k"这种状态下,x,y这个位置是否走过。

用二进制存得到钥匙的状态,用4位即可。

上代码:


#include <iostream>#include <stdio.h>#include <string.h>#include <queue>using namespace std;typedef struct ac{    int x,y,t;    int k;          //用二进制存4把钥匙}node;int dirx[]={0,1,0,-1},diry[]={1,0,-1,0};    bool mark[105][105][20];            //判断在有不同的key的各个位置是否出现过int m,n;char key[]={'b','g','y','r'};char door[]={'B','G','Y','R'};char maze[105][105];    void bfs(node s){    queue <node> q;    mark[s.x][s.y][s.k]=true;    q.push(s);    while(!q.empty())    {        node r=q.front();        q.pop();        if(maze[r.x][r.y]=='X')        {            printf("Escape possible in %d steps.\n",r.t);            return ;        }        for(int i=0;i<4;i++)        {            node w=r;            w.x+=dirx[i];            w.y+=diry[i];            w.t++;            if(w.x<0 || w.x>=n || w.y<0 || w.y>=m || maze[w.x][w.y]=='#')//撞墙                continue ;            if(isupper(maze[w.x][w.y]) && maze[w.x][w.y]!='X')  //door            {                for(int i=0;i<4;i++)                {          //找到对应的门,且有该门的钥匙,且在这种状态下的这个位置未走过                    if(maze[w.x][w.y]==door[i] && (w.k & (1<<i)) && (!mark[w.x][w.y][w.k]))                    {                        mark[w.x][w.y][w.k]=true;                        q.push(w);                    }                }            }            else if(islower(maze[w.x][w.y]))    //key            {                for(int i=0;i<4;i++)                {                    if(maze[w.x][w.y]==key[i])                    {                        w.k|=(1<<i);    //key记录得到这把钥匙                        if(!mark[w.x][w.y][w.k])                        {                            mark[w.x][w.y][w.k]=true;                            q.push(w);                        }                    }                }            }            else if(!mark[w.x][w.y][w.k])   //普通的路            {                mark[w.x][w.y][w.k]=true;                q.push(w);            }        }    }    printf("The poor student is trapped!\n");}int main(){    while(scanf("%d %d",&n,&m) && (m ||n))    {        node s;        memset(mark,0,sizeof(mark));        for(int i=0;i<n;i++)        {            scanf("%s",maze[i]);            for(int j=0;j<m;j++)                if(maze[i][j]=='*')                    s.x=i,s.y=j;        }        s.k=0;        s.t=0;        bfs(s);    }    return 0;}






0 0