题目链接: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,那么说明找到了这样的指令可以是所有的"*"都能按照这样的指令到达边界。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <string> 8 #include <map> 9 using namespace std; 10 11 const int MAXN = 14; 12 typedef pair<int,int >Pair; 13 14 char Map[MAXN][MAXN]; 15 int n,m; 16 int dir[4][2] = { {0,1},{-1,0},{1,0},{0,-1} }; 17 vector<Pair >Pos; 18 int next[MAXN][MAXN][4][2]; 19 bool Judge(int x, int y) 20 { 21 if(x >= 1&&x <= n&&y >= 1&&y <=m) 22 return true; 23 return false; 24 } 25 bool mark[MAXN][MAXN]; 26 bool dfs(int x, int y) 27 { 28 mark[x][y] = true; 29 for(int i = 0; i < 4; i++){ 30 int xx = next[x][y][i][0]; 31 int yy = next[x][y][i][1]; 32 if(!Judge(xx,yy))return true; 33 if(mark[xx][yy])continue; 34 if(dfs(xx,yy))return true; 35 } 36 return false; 37 } 38 39 bool Check() 40 { 41 for(int i = 0; i <(int)Pos.size(); i++){ 42 Pair pp = Pos[i]; 43 memset(mark, false, sizeof(mark)); 44 int xx = pp.first, yy = pp.second; 45 if(!dfs(xx,yy))return false; 46 } 47 return true; 48 } 49 50 string Dir="ENSW"; 51 map<vector<Pair >, string >mp; 52 queue<vector<Pair > >que; 53 54 void bfs() 55 { 56 mp.clear(); 57 while(!que.empty())que.pop(); 58 mp[Pos]=""; 59 que.push(Pos); 60 while(!que.empty()){ 61 vector<Pair >q, p = que.front(); 62 que.pop(); 63 if((int)p.size() == 0){ 64 cout << mp[p] << endl; 65 return ; 66 } 67 for(int i = 0; i < 4; i++){ 68 q.clear(); 69 for(int j = 0; j <(int)p.size(); j++){ 70 Pair pp = p[j]; 71 int xx = next[pp.first][pp.second][i][0]; 72 int yy = next[pp.first][pp.second][i][1]; 73 if(!Judge(xx,yy))continue; 74 q.push_back(make_pair(xx,yy)); 75 } 76 sort(q.begin(), q.end()); 77 q.erase(unique(q.begin(),q.end()),q.end()); 78 if(mp.find(q) == mp.end()){ 79 mp[q] = mp[p] + Dir[i]; 80 que.push(q); 81 } 82 } 83 } 84 puts("Impossible"); 85 } 86 87 int main() 88 { 89 int _case,t=1; 90 scanf("%d", &_case); 91 while(_case--){ 92 Pos.clear(); 93 scanf("%d %d", &n, &m); 94 for(int i = 1; i <= n; i++){ 95 scanf("%s", Map[i] + 1); 96 } 97 for(int i = 1; i <= n; i++){ 98 for(int j = 1; j <= m; j++){ 99 if(Map[i][j] != '#'){ 100 Pos.push_back(make_pair(i,j)); 101 for(int k = 0; k < 4; k++){ 102 int x = i, y = j; 103 while(Judge(x,y)){ 104 if(Map[x][y] == '#'){ 105 x -= dir[k][0]; 106 y -= dir[k][1]; 107 break; 108 } 109 x += dir[k][0]; 110 y += dir[k][1]; 111 } 112 next[i][j][k][0] = x; 113 next[i][j][k][1] = y; 114 } 115 } 116 } 117 } 118 printf("Case %d: ", t++); 119 if(!Check()){ 120 puts("Impossible"); 121 continue; 122 } 123 bfs(); 124 } 125 return 0; 126 } 127 128 129