题目链接:hdu 5025
给出一张图,K表示起点位置,T表示终点位置,S表示有蛇的房间,走过带蛇的房间的时候需要额外的一点时间,数字表示钥匙,#表示不可达,'.'表示普通路,要到终点时必须拿到第k把钥匙。
拿钥匙的规则,要拿第n把钥匙,需要首先拿到第n-1把钥匙。
bfs,需要记录每个点的时间t,已经拿到的钥匙v,二进制保存已经杀过的蛇,然后用宽搜找出最优解
vis[x][y][v][s] 表示点(x,y)拿到钥匙v,杀过蛇的状态s是否访问过来标记访问状态
/******************************************************
* File Name: 1004.cpp
* Author: kojimai
* Creater Time:2014年09月20日 星期六 13时31分59秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define FFF 105
char s[FFF][FFF];
bool vis[105][105][10][32];
int move[4][2]={
-1,0,1,0,0,1,0,-1
};
struct node
{
int x,y,t,v,snake;
bool operator < (const node &a) const{
return t>a.t;
}
};
priority_queue<node> p;
int main()
{
int n,k,sx,sy,ex,ey;
while(scanf("%d%d",&n,&k),n+k)
{
memset(vis,false,sizeof(vis));
while(!p.empty())
{
p.pop();
}
int nw=0;
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
for(int j=0;j<n;j++)
{
if(s[i][j]=='K')
{
sx=i;
sy=j;
}
else if(s[i][j]=='T')
{
ex=i;
ey=j;
}
else if(s[i][j]=='S')
{
s[i][j]='a'+nw++;
}
}
}
node now;
now.x=sx;now.y=sy;now.t=0;now.v=0;now.snake=0;
p.push(now);
vis[now.x][now.y][0][0]=true;
int ans=-1;
node tmp;
while(!p.empty())
{
if(ans!=-1)
break;
now=p.top();p.pop();
//cout<<"x="<<now.x<<" y="<<now.y<<" t="<<now.t<<" v="<<now.v<<" snake="<<now.snake<<endl;
int xx,yy;
for(int i=0;i<4;i++)
{
xx=now.x+move[i][0];yy=now.y+move[i][1];
tmp.x=xx;tmp.y=yy;tmp.t=now.t+1;tmp.v=now.v;tmp.snake=now.snake;
if(xx<0||xx>=n||yy<0||yy>=n||s[xx][yy]=='#')
continue;
if(s[xx][yy]=='T')//t
{
if(now.v==k)
{
ans=now.t+1;
break;
}
}
else if(s[xx][yy]>='1'&&s[xx][yy]<='0'+k)//key
{
if(now.v+1==s[xx][yy]-'0')
{
tmp.v=now.v+1;
}
}
else if(s[xx][yy]>='a'&&s[xx][yy]<'a'+nw)//snake
{
int sna=s[xx][yy]-'a';
if(!(now.snake&(1<<sna)))
{
tmp.t=now.t+2;
tmp.snake|=(1<<sna);
}
}
if(!vis[xx][yy][tmp.v][tmp.snake])
{
//cout<<" tmp x="<<tmp.x<<" y="<<tmp.y<<" t="<<tmp.t<<" v="<<tmp.v<<" snake="<<tmp.snake<<endl;
vis[xx][yy][tmp.v][tmp.snake]=true;
p.push(tmp);
}
}
}
if(ans==-1)
printf("impossible\n");
else
printf("%d\n",ans);
}
return 0;
}