很好的搜索,写起来条件考虑很多很繁琐,交上去各种自挂东南枝,最后写了个数据生成与标称对拍查错,搞了2小时总算AC了。
ACcode:
#include<cstdio>
#include<cstring>
#include<algorithm>
using std::min;
const int NS=222;
const int MS=9;
const int INF=0x3f3f3f3f;
struct node{
int x,y,st;
node(){}
node(int tx,int ty,int tst):
x(tx),y(ty),st(tst){}
}que[1<<15];
int n,m;
int edx,edy,top;
char ch[NS][NS];
int px[MS],py[MS];
int dis[MS][4][MS][4];
int f[NS][NS][4];
int dp[1<<MS][MS][4];
int trans[NS];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void init()
{
trans['U']=0,trans['R']=1,trans['D']=2,
trans['L']=3,trans['.']=4,trans['S']=4;
trans['K']=4,trans['E']=4,trans['#']=9;
}
int boundary(int x,int y)
{
if (x<0||x>=n) return 0;
if (y<0||y>=m) return 0;
return 1;
}
void bfs(int x,int y,int dir)
{
memset(f,0x3f,sizeof(f));
int cx=x+dx[dir];
int cy=y+dy[dir];
int st=0,lft=0,rgt=0;
f[x][y][dir]=0;
if ( !boundary(cx,cy) || ch[cx][cy]=='#' ) return ;
int tx=cx,ty=cy;
while ( boundary(tx,ty) && ch[tx][ty]!='#' && f[tx][ty][dir]>st)
{
f[tx][ty][dir]=st;
if (trans[ch[tx][ty]]<4)
{
dir=trans[ch[tx][ty]];
f[tx][ty][dir]=st;
}
tx+=dx[dir],ty+=dy[dir];
}
if (!boundary(tx,ty) || ch[tx][ty]!='#') return ;
tx-=dx[dir],ty-=dy[dir];
if (ch[tx][ty]=='.')
que[rgt++]=node(tx,ty,st);
while (lft<rgt)
{
cx=que[lft].x;
cy=que[lft].y;
st=que[lft++].st+1;
for (int i=0;i<4;i++)
{
dir=i;
tx=cx+dx[i];
ty=cy+dy[i];
f[cx][cy][dir]=min(st,f[cx][cy][dir]);
if ( !boundary(tx,ty) || ch[tx][ty]=='#' || f[tx][ty][dir]<=st) continue;
while ( boundary(tx,ty) && ch[tx][ty]!='#' && f[tx][ty][dir]>st)
{
f[tx][ty][dir]=st;
int tmp=trans[ch[tx][ty]];
if (tmp<4)
{
dir=tmp;
f[tx][ty][dir]=st;
}
tx+=dx[dir],ty+=dy[dir];
}
if (!boundary(tx,ty) || ch[tx][ty]!='#') continue;
tx-=dx[dir],ty-=dy[dir];
if (ch[tx][ty]=='.')
que[rgt++]=node(tx,ty,st);
}
}
}
int main()
{
init();
while (~scanf("%d %d",&n,&m))
{
top=1;
for (int i=0;i<n;i++)
{
scanf("%s",ch[i]);
for (int j=0;j<m;j++)
{
char tmp=ch[i][j];
if (tmp=='K')
px[top]=i,py[top++]=j;
if (tmp=='S')
px[0]=i,py[0]=j;
if (tmp=='E')
edx=i,edy=j;
if( trans[tmp]==4)
ch[i][j]='.';
}
}
px[top]=edx,py[top]=edy;
for (int i=0;i<top;i++)
for (int j=0;j<4;j++)
{
bfs(px[i],py[i],j);
for (int ei=0;ei<=top;ei++)
for (int ej=0;ej<4;ej++)
dis[i][j][ei][ej]=f[px[ei]][py[ei]][ej];
}
int lim=1<<(top+1);
memset(dp,0x3f,sizeof(dp));
for (int i=0;i<4;i++)
dp[1][0][i]=1;
for (int i=3;i<lim;i+=2)
for (int j=1;j<=top;j++)
if (i&(1<<j))
{
int sta=i^(1<<j);
for (int d=0;d<4;d++)
for (int a=0;a<top;a++)
if (sta&(1<<a))
{
for (int b=0;b<4;b++)
dp[i][j][d]=min(dp[i][j][d],dp[sta][a][b]+dis[a][b][j][d]);
}
}
int ans=INF;
for (int i=0;i<4;i++)
ans=min(ans,dp[lim-1][top][i]);
if (ans>=INF) ans=-1;
printf("%d\n",ans);
}
return 0;
}
/*
1 5
SEK.#
1 4
SEK#
1 3
SE#
1 5
SE.#K
4 4
.#L#
.RS#
.RKE
#DUD
4 4
####
#K.D
#DS#
#ELD
*/