即使czhou没有派出最强篮球阵容,机房篮球队还是暴虐了校篮球队。为了不打击校篮球队信心,czhou决定改变训练后的活动。近来,江大掌门的徒弟徒孙们纷纷事业有成,回到母校为机房捐钱捐物。财大气粗的机房组收回了五层六层的所有教室。Czhou决定将六层的教室改造为智能密室逃脱活动室。
每天傍晚,神牛们可以依次逐个进入游玩。我们简单的将教室分割为n*n个房间,K是你初始所在房间,T是你最终逃脱的房间。如果你想要逃脱房间,你必须依次找到m把钥匙。我们假定你从一个房间进入另一个房间需要花费1的时间。当然某些房间有些特殊的问题(地图上S表示)需要回答才能通过,对于机智的众牛们来说,这些问题根本不是问题。我们假定众牛们花费1的时间解决问题。(主要是出题的人表述不清,导致众牛理解困难;当然问题只需要回答一次,下次再次进入房间不需要回答了)
需要最少时间逃脱密室。若无解输出impossible
经典的分层图搜索,应为s很小,可以状压或暴搜走那些s,然后将这些s看做‘.’用广搜在分层图上跑。
#include
#include
#include
#include
#include
#include
#define inf 1<<30
#define mod 100002
using namespace std;
int n,m,sx,sy,ex,ey,tot;
struct fang{int x,y;} a[10];
char ch[105][105];
int f[102][102][10],ans=inf;
int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
int qx[100005],qy[100005],qv[100005];
void init()
{
scanf("%d%d",&n,&m);
int i,j;
for(i=1;i<=n;i++)
{scanf("%s",ch[i]+1);
for(j=1;j<=n;j++)
{if(ch[i][j]=='K') {sx=i;sy=j;}
else if(ch[i][j]=='T') {ex=i; ey=j;}
else if(ch[i][j]=='S')
{tot++; a[tot].x=i; a[tot].y=j;}
}
}
}
bool check(int x,int y,int v)
{
if(x<1||y<1||x>n||y>n) return true;
if(ch[x][y]=='#'||f[x][y][v]!=-1) return true;
return false;
}
void bfs()
{
memset(f,-1,sizeof(f));
qx[0]=sx; qy[0]=sy; qv[0]=0;
int t=0,w=1,i,xn,yn,vn,xt,yt,vt;
f[sx][sy][0]=0;
while(t!=w)
{xn=qx[t]; yn=qy[t]; vn=qv[t]; t=(t+1)%mod;
for(i=0;i<4;i++)
{xt=xn+xx[i]; yt=yn+yy[i]; vt=vn;
if(check(xt,yt,vt)) continue;
if(vn+1==ch[xt][yt]-'0') vt++;
f[xt][yt][vt]=f[xn][yn][vn]+1;
qx[w]=xt; qy[w]=yt; qv[w]=vt;
w=(w+1)%mod;
}
}
}
void dfs(int w,int ct)
{
if(w==tot+1)
{bfs();
if(f[ex][ey][m]!=-1) ans=min(ans,ct+f[ex][ey][m]);
return ;
}
ch[a[w].x][a[w].y]='.';
dfs(w+1,ct+1);
ch[a[w].x][a[w].y]='#';
dfs(w+1,ct);
}
int main()
{
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
init(); dfs(1,0);
if(ans!=inf)printf("%d\n",ans);
else puts("impossible");
return 0;
}