http://acm.hdu.edu.cn/showproblem.php?pid=1429
因为图中需要记录钥匙的拥有情况,所以需要用状态压缩的思想,来用一个数字表示对应二进制位数上的钥匙有无情况
再结合bfs即可
#include<bits/stdc++.h>
using namespace std;
struct node{
int x;
int y;
int step;
int ks;
};
int n,m,tim;
int key[22][22];
int door[22][22];
int ma[22][22];
char s[22][22];
int sx,sy;
int ex,ey;
int vis[22][22][(1<<10)];
bool check(int x,int y,int zt)
{
if(x>=0&&x<n&&y>=0&&y<m&&ma[x][y]==0)
{
if(vis[x][y][zt]==1)return 0;
if((door[x][y]&zt)==door[x][y])
return 1;
return 0;
}
return 0;
}
int search()
{
node t,tt;
t.x=sx;
t.y=sy;
t.step=0;
t.ks=0;
queue<node >p;
p.push(t);
vis[sx][sy][0]=1;
while(!p.empty())
{
t=p.front();
p.pop();
if(t.x==ex&&t.y==ey)
{
return t.step;
}
if(check(t.x+1,t.y,t.ks))
{
tt.x=t.x+1;
tt.y=t.y;
tt.step=t.step+1;
tt.ks=(t.ks|key[t.x+1][t.y]);
vis[tt.x][tt.y][tt.ks]=1;
p.push(tt);
}
if(check(t.x-1,t.y,t.ks))
{
tt.x=t.x-1;
tt.y=t.y;
tt.step=t.step+1;
tt.ks=(t.ks|key[t.x-1][t.y]);
vis[tt.x][tt.y][tt.ks]=1;
p.push(tt);
}
if(check(t.x,t.y+1,t.ks))
{
tt.x=t.x;
tt.y=t.y+1;
tt.step=t.step+1;
tt.ks=(t.ks|key[t.x][t.y+1]);
vis[tt.x][tt.y][tt.ks]=1;
p.push(tt);
}
if(check(t.x,t.y-1,t.ks))
{
tt.x=t.x;
tt.y=t.y-1;
tt.step=t.step+1;
tt.ks=(t.ks|key[t.x][t.y-1]);
vis[tt.x][tt.y][tt.ks]=1;
p.push(tt);
}
}
}
int main(){
while(cin>>n>>m>>tim)
{
memset(key,0,sizeof(key));
memset(vis,0,sizeof(vis));
memset(ma,0,sizeof(ma));
memset(door,0,sizeof(door));
for(int i=0;i<n;i++)
cin>>s[i];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(s[i][j]=='*')
{
ma[i][j]=1;
}
if(s[i][j]=='@')sx=i,sy=j;
if(s[i][j]=='^')ex=i,ey=j;
if(s[i][j]>='a'&&s[i][j]<='z')
key[i][j]=(1<<(s[i][j]-'a'));
if(s[i][j]>='A'&&s[i][j]<='Z')
door[i][j]=(1<<(s[i][j]-'A'));
}
int ans=search();
if(ans>=tim)
{
cout<<"-1"<<endl;
}
else cout<<ans<<endl;
}
return 0;
}