题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1885
思路:用四位二进制数每一位表示是否拥有一种钥匙,若当前状态与当前门取&不为0表示可通过;若遇到钥匙,则取|,表示拥有此种钥匙。用v[x][y][state]表示在(x,y)位置,拥有钥匙状态。
#include<map>
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
const int maxn=100+10;
const int dx[]= {-1,1,0,0};
const int dy[]= {0,0,-1,1};
struct Node
{
int x,y,state,step;
Node(int x=0,int y=0,int state=0,int step=0):x(x),y(y),state(state),step(step) {}
};
int n,m,stx,sty;
queue<Node> q;
char g[maxn][maxn];
map<char,int> col,COL;
int v[maxn][maxn][35];
int inside(int x,int y)
{
return x>=1&&x<=n&&y>=1&&y<=m&&g[x][y]!='#';
}
int solve(int x,int y)
{
memset(v,0,sizeof(v));
while(!q.empty()) q.pop();
q.push(Node(x,y,0,0));
v[x][y][0]=1;
while(!q.empty())
{
Node now=q.front();
q.pop();
for(int i=0; i<4; i++)
{
int x=now.x+dx[i];
int y=now.y+dy[i];
int state=now.state;
int step=now.step+1;
if(inside(x,y))
{
//cout<<"* "<<now.x<<" "<<now.y<<" "<<state<<" "<<x<<" "<<y<<" "<<g[x][y]<<" "<<state<<endl;
switch (g[x][y])
{
case 'B':
case 'Y':
case 'R':
case 'G':
{
int tmp=state&(1<<COL[g[x][y]]);
//cout<<now.x<<" "<<now.y<<" "<<state<<" "<<x<<" "<<y<<" "<<state<<" "<<g[x][y]<<endl;
if(!v[x][y][state]&&tmp)
{
v[x][y][state]=1;
q.push(Node(x,y,state,step));
}
break;
}
case 'b':
case 'y':
case 'r':
case 'g':
{
int tmp=state|(1<<col[g[x][y]]);
//cout<<now.x<<" "<<now.y<<" "<<state<<" "<<x<<" "<<y<<" "<<tmp<<" "<<g[x][y]<<endl;
if(!v[x][y][tmp])
{
v[x][y][tmp]=1;
q.push(Node(x,y,tmp,step));
}
break;
}
case '.':
{
//cout<<now.x<<" "<<now.y<<" "<<state<<" "<<x<<" "<<y<<" "<<state<<" "<<"."<<endl;
if(!v[x][y][state])
{
v[x][y][state]=1;
q.push(Node(x,y,state,step));
}
break;
}
case 'X':
{
return step;
}
case '*':
{
if(!v[x][y][state])
{
v[x][y][state]=1;
q.push(Node(x,y,state,step));
}
break;
}
}
}
}
}
return -1;
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
#endif // debug
col['b']=0,col['y']=1,col['r']=2,col['g']=3;
COL['B']=0,COL['Y']=1,COL['R']=2,COL['G']=3;
while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
{
getchar();
stx=sty=-1;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
char ch;
scanf("%c",&ch);
g[i][j]=ch;
if(ch=='*') stx=i,sty=j;
}
getchar();
}
//cout<<stx<<" "<<sty<<endl;
int ans=solve(stx,sty);
if(ans!=-1) printf("Escape possible in %d steps.\n",ans);
else printf("The poor student is trapped!\n");
}
return 0;
}