题意:
给出一个地图,#是墙 K是起点T是终点数字是钥匙,S是蛇,经过此处需要2秒,而如果第二次经过同一个S,第二次需要1秒,钥匙只是一个个拿,按数字大小。 在到达终点时候需要拿到所有钥匙
思路:
将蛇状压编号,将钥匙记录状态是第几个
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N = 105;
int vis[N][N][1 << 5+1][10];
int dir[4][2] = {{-1, 0},{1, 0},{0, 1},{0, -1}};
char mp[N][N];
int snak[N][N];
struct node{
int x,y;
int key;
int snake;
int step;
bool operator <(node a)const{
return step>a.step;
}
};
int ans;
int n,m;
const int inf=0x3f;
void bfs(int sx,int sy)
{
node start;
start.x=sx,start.y=sy;
start.snake=0,start.step=0;
start.key=0;
priority_queue<node> q;
q.push(start);
vis[sx][sy][0][0]=1;
while(!q.empty())
{
node t=q.top();
q.pop();
for(int i=0;i<4;i++)
{
node tmp=t;
tmp.x+=dir[i][0];
tmp.y+=dir[i][1];
tmp.step++;
if(tmp.x<1||tmp.y<1||tmp.x>n||tmp.y>n||vis[tmp.x][tmp.y][tmp.snake][tmp.key]||mp[tmp.x][tmp.y]=='#')
{
continue;
}
if(mp[tmp.x][tmp.y]=='S')
{
int nowsnake=tmp.snake;
if(nowsnake&(1<<snak[tmp.x][tmp.y]))
{
q.push(tmp);
}else{
tmp.snake|=(1<<snak[tmp.x][tmp.y]);
tmp.step++;
q.push(tmp);
}
}
else if(mp[tmp.x][tmp.y]-'0'==tmp.key+1)
{
tmp.key++;
q.push(tmp);
}
else if(mp[tmp.x][tmp.y]=='T'&&tmp.key==m)
{
ans=tmp.step;
return;
}
else{
q.push(tmp);
}
vis[tmp.x][tmp.y][tmp.snake][tmp.key]=1;
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)break;
memset(vis,0,sizeof(vis));
ans=inf;
int cnt=0;
int sx,sy;
for(int i=1;i<=n;i++)
scanf("%s",&mp[i][1]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(mp[i][j]=='S')
snak[i][j]=++cnt;
if(mp[i][j]=='K')
sx=i,sy=j;
}
}
bfs(sx,sy);
if(ans==inf)
printf("impossible");
else printf("%d",ans);
printf("\n");
}
}