http://acm.hdu.edu.cn/showproblem.php?pid=5025
TLE了好几次
写的时候,问题在于,
1、钥匙怎么处理
参考了他人的写法,vis[key_num][i][j],相当于将图多维化,这样就可以判重了,否则只是按照普通的BFS,钥匙数不同的时候,可以重复,这个代码难易表达出来
另外此处一个很好的优化,当cost_now<cost[key_now][x_now][y_now]的时候,才q.push(Node) 这个剪枝很好啊
2、蛇怎么处理
没蛇的话,第一次搜到的可行解就是最优解,
有蛇的话,需要解决1、第一次遇到蛇杀死,以后遇到不杀,这个用set存储,每次find,注意只把曾经有蛇的地方insert,因为蛇只有5个,所以这个空间是开的下的,时间也承受的住 2、彻底将图搜完才可以结束搜索
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const double pi = acos(-1.0);
const int INF = 100000000;
const int MAXN = 100+10;
int n,m,kx,ky,tx,ty;
char mat[MAXN][MAXN];
int vis[10][MAXN][MAXN];
struct Node{
int x,y,k,cost;
Node(){};
Node(int xx,int yy,int kk, int cc){x=xx;y=yy;k=kk;cost=cc;}
set< pair<int, int> >s;
};
int dir[4][2]={ {-1,0},{0,-1},{1,0},{0,1} };
queue<Node>q;
bool legal(int x, int y)
{
if(x>=0 && y>=0 && x<n && y<n)return 1;
else return 0;
}
int bfs()
{
int ret=INF;
q.push( Node(kx,ky,0,0) );
CL(vis,0xff);
while(!q.empty())
{
Node tmp=q.front();q.pop();
for(int i=0;i<4;i++)
{
int x=tmp.x+dir[i][0];
int y=tmp.y+dir[i][1];
if(mat[x][y]=='#' || !legal(x,y))continue;
Node nxt=tmp;
nxt.x=x;
nxt.y=y;
nxt.cost++;
if(mat[x][y] >= '1' && mat[x][y] <='9')
{
int num=mat[x][y]-'1';
if(num == tmp.k)
{
nxt.k=num+1;
}
}
if(mat[x][y] == 'S' && tmp.s.find(make_pair(x,y)) == tmp.s.end())
{
nxt.cost++;
nxt.s.insert(make_pair(x,y));
}
if(vis[nxt.k][x][y]>nxt.cost || vis[nxt.k][x][y]==-1)
{
vis[nxt.k][x][y]=nxt.cost;
q.push(nxt);
}
}
}
return vis[m][tx][ty];
}
int main()
{
//IN("hdu5025.txt");
while(~scanf("%d%d",&n,&m) && n+m)
{
getchar();
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
mat[i][j]=getchar();
if(mat[i][j] == 'K'){kx=i;ky=j;}
if(mat[i][j] == 'T'){tx=i;ty=j;}
}
getchar();
}
while(!q.empty())q.pop();
int ans=bfs();
if(ans == -1)printf("impossible\n");
else printf("%d\n",bfs());
}
return 0;
}