题目链接:http://lightoj.com/volume_showproblem.php?problem=1426
思路:首先我们预处理出每一个"*"在某一方向上最终能到达的位置,这里我们可以用一个四维数组来记录next[i][j][k][2],然后首先判断"impossible"这种情况,我们可以对每个"*"进行dfs,看是否能够到达边界,如果存在某个“*”不能到达边界,那么直接就是"impossible“了。判断好这个之后就可以直接bfs求解了,这里我们用map<vector<int,int>,string >mp来判重,我们可以枚举4个方向,然后对于那些不能到达边界的点,加入到一个vector向量中,如果最后我们能够找到一个为空的vector,那么说明找到了这样的指令可以是所有的"*"都能按照这样的指令到达边界。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <map>
using namespace std; const int MAXN = ;
typedef pair<int,int >Pair; char Map[MAXN][MAXN];
int n,m;
int dir[][] = { {,},{-,},{,},{,-} };
vector<Pair >Pos;
int next[MAXN][MAXN][][];
bool Judge(int x, int y)
{
if(x >= &&x <= n&&y >= &&y <=m)
return true;
return false;
}
bool mark[MAXN][MAXN];
bool dfs(int x, int y)
{
mark[x][y] = true;
for(int i = ; i < ; i++){
int xx = next[x][y][i][];
int yy = next[x][y][i][];
if(!Judge(xx,yy))return true;
if(mark[xx][yy])continue;
if(dfs(xx,yy))return true;
}
return false;
} bool Check()
{
for(int i = ; i <(int)Pos.size(); i++){
Pair pp = Pos[i];
memset(mark, false, sizeof(mark));
int xx = pp.first, yy = pp.second;
if(!dfs(xx,yy))return false;
}
return true;
} string Dir="ENSW";
map<vector<Pair >, string >mp;
queue<vector<Pair > >que; void bfs()
{
mp.clear();
while(!que.empty())que.pop();
mp[Pos]="";
que.push(Pos);
while(!que.empty()){
vector<Pair >q, p = que.front();
que.pop();
if((int)p.size() == ){
cout << mp[p] << endl;
return ;
}
for(int i = ; i < ; i++){
q.clear();
for(int j = ; j <(int)p.size(); j++){
Pair pp = p[j];
int xx = next[pp.first][pp.second][i][];
int yy = next[pp.first][pp.second][i][];
if(!Judge(xx,yy))continue;
q.push_back(make_pair(xx,yy));
}
sort(q.begin(), q.end());
q.erase(unique(q.begin(),q.end()),q.end());
if(mp.find(q) == mp.end()){
mp[q] = mp[p] + Dir[i];
que.push(q);
}
}
}
puts("Impossible");
} int main()
{
int _case,t=;
scanf("%d", &_case);
while(_case--){
Pos.clear();
scanf("%d %d", &n, &m);
for(int i = ; i <= n; i++){
scanf("%s", Map[i] + );
}
for(int i = ; i <= n; i++){
for(int j = ; j <= m; j++){
if(Map[i][j] != '#'){
Pos.push_back(make_pair(i,j));
for(int k = ; k < ; k++){
int x = i, y = j;
while(Judge(x,y)){
if(Map[x][y] == '#'){
x -= dir[k][];
y -= dir[k][];
break;
}
x += dir[k][];
y += dir[k][];
}
next[i][j][k][] = x;
next[i][j][k][] = y;
}
}
}
}
printf("Case %d: ", t++);
if(!Check()){
puts("Impossible");
continue;
}
bfs();
}
return ;
}