紫书的这道题, 作者说是很重要。
但看着题解好长, 加上那段时间有别的事, 磨了几天没有动手。
最后,这道题我打了五遍以上 ,有两次被BUG卡了,找了很久才找到。
思路紫书上有,就缺少输入和边界判断两个部分。不是因为紫书,应该也不会找到这个WF题吧,所以其余思路就不说了。 一些注释在代码中有。
代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <vector> 5 #include <queue> 6 using namespace std; 7 8 const int MAXN = 10; 9 const char* dirs = "NESW"; 10 const char* turns = "FLR"; 11 int dir_id(char c) {return strchr(dirs, c)-dirs;} 12 int turn_id(char c) {return strchr(turns, c)-turns;} 13 const int dr[] = {-1, 0, 1, 0}; 14 const int dc[] = {0, 1, 0, -1}; 15 16 struct Node 17 { 18 int r; 19 int c; 20 int dir; 21 Node(int rr=0, int cc=0, int d=0):r(rr), c(cc), dir(d) {} 22 }; 23 24 int has_edge[MAXN][MAXN][4][3]; 25 int d[MAXN][MAXN][4];//判断是否遍历过 26 Node p[MAXN][MAXN][4]; 27 int r0, c0, r1, c1, r2, c2, dir; 28 29 30 Node walk(const Node& u, int turn) 31 { 32 int dir=u.dir; 33 if(turn==1) dir = (dir+3)%4;//逆时针 34 if(turn==2) dir = (dir+1)%4;//顺时针 35 return Node(u.r+dr[dir], u.c+dc[dir], dir); 36 } 37 38 bool inside(int r, int c)//判断是否出界 39 { 40 return r>=1 && r<=9 && c>=1 && c<=9; 41 } 42 43 bool read_case() 44 { 45 char s1[99], s2[99];//储存名字, 储存方向 46 if(scanf("%s%d%d%s%d%d", s1, &r0, &c0, s2, &r2, &c2)!=6) return false;//输入不正确 47 printf("%s\n", s1); 48 memset(has_edge, 0, sizeof(has_edge)); 49 50 dir = dir_id(s2[0]); 51 r1 = r0+dr[dir]; 52 c1 = c0+dc[dir]; 53 54 for(; ;) 55 { 56 int r, c; 57 scanf("%d", &r); 58 if(r==0) break; 59 scanf("%d", &c); 60 while(scanf("%s", s2)==1 && s2[0]!='*') 61 { 62 int len=strlen(s2); 63 for(int i=1; i<len; i++) 64 has_edge[r][c][dir_id(s2[0])][turn_id(s2[i])]=1;//将可走的地方赋1 65 } 66 } 67 return true; 68 } 69 70 void print_ans(Node u) 71 { 72 vector<Node> nodes; 73 for(; ;)//输入 74 { 75 nodes.push_back(u); 76 if(d[u.r][u.c][u.dir]==0) break; 77 u = p[u.r][u.c][u.dir]; 78 } 79 nodes.push_back(Node(r0, c0, dir));//起点存入 80 81 int cnt=0; 82 for(int i=nodes.size()-1; i>=0; i--)//倒着输出 83 { 84 // cout<<"#i"<<endl; 85 if(cnt%10 == 0) printf(" "); 86 printf(" (%d,%d)", nodes[i].r, nodes[i].c); 87 if(++cnt % 10 ==0) printf("\n"); 88 } 89 if(nodes.size()%10!=0) printf("\n"); 90 } 91 92 void solve() 93 { 94 queue<Node> q; 95 memset(d, -1, sizeof(d)); 96 Node u(r1, c1, dir); 97 d[u.r][u.c][u.dir]=0; 98 q.push(u); 99 while(!q.empty()) 100 { 101 Node now = q.front(); q.pop(); 102 if(now.r==r2 && now.c==c2) 103 { 104 print_ans(now); 105 return; 106 } 107 108 for(int i=0; i<3; i++) 109 { 110 Node v = walk(now, i); 111 if(has_edge[now.r][now.c][now.dir][i] && d[v.r][v.c][v.dir]<0 && inside(v.r, v.c)) 112 { 113 d[v.r][v.c][v.dir] = d[now.r][now.c][now.dir]+1; 114 p[v.r][v.c][v.dir] = now; 115 q.push(v); 116 } 117 } 118 } 119 printf(" No Solution Possible\n"); 120 } 121 122 int main() 123 { 124 while(read_case()) 125 solve(); 126 127 return 0; 128 }
毕竟完成了一题WF题,虽然开始的思路不是自己想的,但还是感觉有一丝丝成就感,哈哈。