题意:地图上K开始按照1~m的顺序取完所有钥匙到达T的最小步数,如果遇到step+1,再次遇到不加
题解:以一个四维状态数组表示当前状态是否被访问过,四维分别为,x,y坐标维,钥匙状态,S状态
#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");
using namespace std;
#define INF 0x3f3f3f3f
int snk[105][105];
char g[105][105];
bool vis[105][105][11][(1<<6)+1];
int dir[][5]= {{0,1},{0,-1},{1,0},{-1,0}};
int n,m;
struct node
{
int x,y;
int key,snk;
int step;
friend bool operator < (node A,node B)
{
return A.step>B.step;
}
} s;
void init()
{
memset(snk,0,sizeof snk);
memset(vis,0,sizeof vis);
}
bool inbound(int x,int y)
{
return x>=0&&x<n&&y>=0&&y<n;
}
priority_queue<node>que;
int bfs()
{
while(que.size()) que.pop();
que.push(s);
vis[s.x][s.y][s.key][s.snk]=true;
while(que.size())
{
s=que.top();
que.pop();
for(int i=0; i<4; i++)
{
node k=s;
k.x+=dir[i][0];
k.y+=dir[i][1];
k.step++;
if(inbound(k.x,k.y)&&!vis[k.x][k.y][k.key][k.snk]&&g[k.x][k.y]!='#')
{
vis[k.x][k.y][k.key][k.snk]=true;
if(g[k.x][k.y]>='0'&&g[k.x][k.y]<='9')
{
if(g[k.x][k.y]-'0'==k.key+1) k.key++;
que.push(k);
}
else if(g[k.x][k.y]=='S')
{
int num=snk[k.x][k.y];
if((k.snk&(1<<num))==false) k.step++,k.snk|=(1<<num);
que.push(k);
}
else if(g[k.x][k.y]=='T')
{
if(k.key==m)
{
return k.step;
}
que.push(k);
}
else
{
que.push(k);
}
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF&&n+m)
{
init();
int cnt=1;
for(int i=0; i<n; i++) scanf("%s",g[i]);
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(g[i][j]=='K')
{
s.x=i;
s.y=j;
s.step=0;
s.key=0;
s.snk=0;
}
else if(g[i][j]=='S')
{
snk[i][j]=cnt++;
}
}
}
int ans=bfs();
if(ans==-1) printf("impossible\n");
else printf("%d\n",ans);
}
return 0;
}