hdu1885 Key Task
刚开始看到这题都吓到了,第一感觉就是不能记录已走过的点,一旦记录了,那假设钥匙在对面,门在这边,那拿完钥匙就回不来了;
可是,如果不记录的话,那岂不是在整个地图了乱窜,绝对超时,甚至是死循环;
之后,想了想,把每个点在入队列的时候,记录下状态每一个点的状态,即又有没有拿到钥匙,拿到哪几种钥匙之类的,如果回溯时,俩点的状态一样,则没必要入队,这确实是一种可行的办法,可是想到这里,突然,想到,要对每一个点保存16种状态,那内存肯定要爆了呀,结果思路就这么停了,想不出别的办法了……
查了一下,原来记录状态是用位运算保存呀,郁闷呐,亏我知道这东西存在,亏我还用过位运算保存过一个数字是否出现过,结果我居然一点都没想到,惭愧呀
是这样保存的,开一个三维的数组,flag[101][101][16],记录每一个点的状态,除了坐标之外,保存的是一个点有没有钥匙,有多少把钥匙,每一个位保存一把钥匙的状态,总共十六种状态
假设 // b,y,r, g 钥匙分别用二进制的第一,二,三,四位保存,flag&1 ==1 表示 该状态b钥匙已经有了,当拿到b钥匙时,flag|=1,记录下来。
#include<iostream>
#include<queue>
using namespace std;
char map[101][101];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}},n,m;
int flag[101][101][16];
// b,y,r, g: 1,2,4,8
struct node
{
int x,y,cnt,v;
node(int _x=0,int _y=0,int _cnt=0 ,int _v=0):x(_x),y(_y),cnt(_cnt),v(_v){};
friend bool operator <(const node &a,const node &b)
{
return a.cnt>b.cnt;
}
};
node f;
bool OK(int i,int j,int va)
{
if(map[i][j]=='B'&&(va&1))
return true;
if(map[i][j]=='Y'&&(va&2))
return true;
if(map[i][j]=='R'&&(va&4))
return true;
if(map[i][j]=='G'&&(va&8))
return true;
return false;
}
int bfs()
{
flag[f.x][f.y][f.v]=1;
priority_queue<node> Q;
Q.push(f);
while(!Q.empty())
{
node t=Q.top();
Q.pop();
for(int k=0;k<4;k++)
{
int i=t.x+dir[k][0];
int j=t.y+dir[k][1];
if(i<n&&i>=0&&j<m&&j>=0&&map[i][j]!='#')
{
if(OK(i,j,t.v)&&!flag[i][j][t.v])
{
flag[i][j][t.v]=1;
Q.push(node(i,j,t.cnt+1,t.v));
}
else if(map[i][j]=='b'&&!flag[i][j][t.v|1])
{
flag[i][j][t.v|1]=1;
Q.push(node(i,j,t.cnt+1,t.v|1));
}
else if(map[i][j]=='y'&&!flag[i][j][t.v|2])
{
flag[i][j][t.v|2]=1;
Q.push(node(i,j,t.cnt+1,t.v|2));
}
else if(map[i][j]=='r'&&!flag[i][j][t.v|4])
{
flag[i][j][t.v|4]=1;
Q.push(node(i,j,t.cnt+1,t.v|4));
}
else if(map[i][j]=='g'&&!flag[i][j][t.v|8])
{
flag[i][j][t.v|8]=1;
Q.push(node(i,j,t.cnt+1,t.v|8));
}
else if(map[i][j]=='.'&&!flag[i][j][t.v])
{
flag[i][j][t.v]=1;
Q.push(node(i,j,t.cnt+1,t.v));
}
else if(map[i][j]=='X')
return t.cnt+1;
}
}
}
return 0;
}
int main()
{
while(cin>>n>>m&&(n||m))
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>map[i][j];
if(map[i][j]=='*')
f.x=i,f.y=j;
}
f.cnt=0;f.v=0;map[f.x][f.y]='.';
memset(flag,0,sizeof(flag));
int t=bfs();
if(t)
cout<<"Escape possible in "<<t<<" steps."<<endl;
else cout<<"The poor student is trapped!"<<endl;
}
return 0;
}

浙公网安备 33010602011771号