注意;UDLR可能构成一个死循环。UDLR正好指向旁边的墙壁,则不能再移动了。
普通的最短路。做题的时候太疲劳了。wa了n次。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <string>
#define LL long long
#define DB double
#define SF scanf
#define SI(a) scanf("%d",&a)
#define SD(a) scanf("%lf",&a)
#define PF printf
#define MM(a,b) memset(a,b,sizeof(a))
#define N 209
#define bug cout<<"bug"<<endl
using namespace std;
const int INF = 0x3f3f3f3f;
char ch[N][N];
struct sty{
int key,x,y;
sty(int a=0,int b=0,int k=0)
{
x = a;y = b;key = k;
}
int operator<(const sty t)const
{
if(key!=t.key) return key-t.key;
if(x!=t.x) return x-t.x;
return y-t.y;
}
}ext,start;
//map<sty,int> mp;
int n,m;
bool oor(int x,int y)
{
if(x<0||x>=n) return false;
if(y<0||y>=m) return false;
return true;
}
int kkey[N][N];
void fin()
{
int tmp = 0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(ch[i][j]=='K')
{
kkey[i][j] = tmp;
tmp++;
}else
{
kkey[i][j] = -1;
}
if(ch[i][j]=='E')
{
ext.x = i;
ext.y = j;
// bug;
}
if(ch[i][j]=='S')
{
start.key = 0;
start.x = i;
start.y = j;
}
}
ext.key = (1<<tmp)-1;
}
queue<sty> que;
int dis[N][N][1<<7];
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
int ANS;
int visit[N][N];
sty get(sty e,int k)
{
if(visit[e.x][e.y]>3) return start;
sty t = e;
int v=e.key;
for(int i=1;;i++)
{
int tx = e.x+dx[k]*i,ty = e.y+dy[k]*i;
if(ch[tx][ty]=='K')
{
v|=(1<<kkey[tx][ty]);
}
if(!oor(tx,ty)) return start;
if(ch[tx][ty]=='#') return t;
t.x = tx;t.y = ty;
t.key = v;
if(t.x==ext.x&&t.y==ext.y&&t.key==ext.key)
{
return t;
}
if(ch[tx][ty]=='L')
{
visit[tx][ty]++;
sty ret= get(t,0);
visit[tx][ty]--;
return ret;
}else if(ch[tx][ty]=='R')
{
visit[tx][ty]++;
sty ret= get(t,1);
visit[tx][ty]--;
return ret;
}else if(ch[tx][ty]=='U')
{
visit[tx][ty]++;
sty ret= get(t,2);
visit[tx][ty]--;
return ret;
}else if(ch[tx][ty]=='D')
{
visit[tx][ty]++;
sty ret= get(t,3);
visit[tx][ty]--;
return ret;
}
}
}
int solve()
{
fin();
// cout<<"ext "<<ext.x<<" "<<ext.y<<" "<<ext.key<<endl;
while(!que.empty()) que.pop();
que.push(start);
sty e,t;
memset(dis,INF,sizeof(dis));
dis[start.x][start.y][start.key] = 0;
//mp[start] = 1;
while(!que.empty())
{
e = que.front();que.pop();
// cout<<e.x<<" "<<e.y<<endl;
for(int i=0;i<4;i++)
{
if(ch[e.x][e.y]=='L'||ch[e.x][e.y]=='D'||ch[e.x][e.y]=='U'||ch[e.x][e.y]=='R')
continue;
t = get(e,i);
if(dis[t.x][t.y][t.key]!=INF) continue;
que.push(t);
// mp[t] = 1;
// cout<<t.x<<" "<<t.y<<" "<<t.key<<" dis = "<<dis[e.x][e.y][e.key]+1<<endl;
dis[t.x][t.y][t.key] = dis[e.x][e.y][e.key]+1;
}
}
if(dis[ext.x][ext.y][ext.key]==INF) return -1;
return dis[ext.x][ext.y][ext.key];
}
int main()
{
while(~SF("%d%d",&n,&m))
{
for(int i=0;i<n;i++)
{
SF("%s",ch[i]);
}
PF("%d\n",solve());
}
return 0;
}