这道题目最开始做的时候wa+TLE。后面知道需要状态压缩,最近A掉。并且练习一下各种搜索算法。
1. 逆向BFS+康拓展开。
1 #include <iostream>
2 #include <queue>
3 #include <cstring>
4 #include <string>
5 #include <cstdio>
6 using namespace std;
7
8 #define N 9
9 #define MAXNUM 362880
10
11 typedef struct {
12 char map[N];
13 int xpos;
14 string path;
15 } node_st;
16
17 int fact[N] = {1,1,2,6,24,120,720,5040,40320};
18 int direct[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
19 char rmove[4] = {‘d‘,‘u‘,‘r‘,‘l‘};
20 char visit[MAXNUM];
21 string rpath[MAXNUM];
22
23 int cantor(node_st node) {
24 int i, j, cnt, val = 0;
25
26 for (i=0; i<N; ++i) {
27 cnt = 0;
28 for (j=i+1; j<N; ++j) {
29 if (node.map[j] < node.map[i])
30 ++cnt;
31 }
32 val += fact[N-1-i]*cnt;
33 }
34
35 return val;
36 }
37
38 void bfs() {
39 queue<node_st> que;
40 node_st node;
41 int i, x, y, t1, t2, can;
42
43 for (i=1; i<N; ++i)
44 node.map[i-1] = ‘0‘ + i;
45 node.map[N-1] = ‘x‘;
46 node.xpos = N-1;
47 memset(visit, 0, sizeof(visit));
48 visit[0] = 1;
49 que.push(node);
50
51 while ( !que.empty() ) {
52 node = que.front();
53 que.pop();
54 t1 = node.xpos / 3;
55 t2 = node.xpos % 3;
56 for (i=0; i<4; ++i) {
57 x = t1 + direct[i][0];
58 y = t2 + direct[i][1];
59 if (x<0 || x>=3 || y<0 || y>=3)
60 continue;
61 node_st tmp(node);
62 tmp.xpos = x*3+y;
63 tmp.map[node.xpos] = node.map[tmp.xpos];
64 tmp.map[tmp.xpos] = ‘x‘;
65 can = cantor(tmp);
66 if ( !visit[can] ) {
67 visit[can] = 1;
68 tmp.path += rmove[i];
69 rpath[can] = tmp.path;
70 que.push(tmp);
71 }
72 }
73 }
74 }
75
76 int main() {
77 node_st node;
78 int i, can;
79
80 bfs();
81
82 while (scanf("%c%*c", &node.map[0]) != EOF) {
83 for (i=1; i<N; ++i)
84 scanf("%c%*c", &node.map[i]);
85 can = cantor(node);
86 if ( visit[can] ) {
87 for (i=rpath[can].size()-1; i>=0; --i)
88 printf("%c", rpath[can][i]);
89 printf("\n");
90 } else {
91 printf("unsolvable\n");
92 }
93 }
94
95 return 0;
96 }
2. 双端BFS。注意逆序奇偶性相同才有解。
1 #include <iostream>
2 #include <queue>
3 #include <string>
4 #include <algorithm>
5 #include <cstring>
6 #include <cstdio>
7 using namespace std;
8
9 #define N 9
10 #define MAXNUM 362880
11
12 typedef struct {
13 char map[N];
14 int xpos;
15 string path;
16 } node_st;
17
18 int fact[N]={1,1,2,6,24,120,720,5040,40320};
19 int direct[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
20 char move[4] = {‘u‘,‘d‘,‘l‘,‘r‘};
21 char rmove[4] = {‘d‘,‘u‘,‘r‘,‘l‘};
22 char visit[MAXNUM];
23 bool flag;
24 string paths[MAXNUM], fpath;
25 queue<node_st> que, rque;
26
27
28 inline int cantor(node_st node) {
29 int i, j, cnt, val = 0;
30
31 for (i=0; i<N; ++i) {
32 cnt = 0;
33 for (j=i+1; j<N; ++j)
34 if (node.map[j] < node.map[i])
35 ++cnt;
36 val += fact[N-1-i]*cnt;
37 }
38
39 return val;
40 }
41
42 inline bool invNum(node_st node) {
43 int i, j, cnt = 0;
44
45 for (i=0; i<N; ++i) {
46 if (node.map[i] == ‘x‘)
47 continue;
48 for (j=i-1; j>=0; --j)
49 if (node.map[j]!=‘x‘ && node.map[j]>node.map[i])
50 ++cnt;
51 }
52
53 return cnt&1;
54 }
55
56 void bfs() {
57 int x, y, can;
58 node_st node = que.front();
59 que.pop();
60
61 for (int i=0; i<4; ++i) {
62 x = node.xpos/3 + direct[i][0];
63 y = node.xpos%3 + direct[i][1];
64 if (x<0 || x>=3 || y<0 || y>=3)
65 continue;
66 node_st p(node);
67 p.map[p.xpos] = node.map[x*3+y];
68 p.xpos = x*3+y;
69 p.map[p.xpos] = ‘x‘;
70 can = cantor(p);
71 if (visit[can] == 1)
72 continue;
73 p.path += move[i];
74 if (visit[can] == -1) {
75 flag = false;
76 reverse(paths[can].begin(), paths[can].end());
77 fpath = p.path + paths[can];
78 return ;
79 }
80 visit[can] = 1;
81 paths[can] = p.path;
82 que.push(p);
83 }
84 }
85
86 void rbfs() {
87 int x, y, can;
88 node_st node = rque.front();
89 rque.pop();
90
91 for (int i=0; i<4; ++i) {
92 x = node.xpos/3 + direct[i][0];
93 y = node.xpos%3 + direct[i][1];
94 if (x<0 || x>=3 || y<0 || y>=3)
95 continue;
96 node_st p(node);
97 p.map[p.xpos] = node.map[x*3+y];
98 p.xpos = x*3+y;
99 p.map[p.xpos] = ‘x‘;
100 can = cantor(p);
101 if (visit[can] == -1)
102 continue;
103 p.path += rmove[i];
104 if (visit[can] == 1) {
105 flag = false;
106 reverse(p.path.begin(), p.path.end());
107 fpath = paths[can] + p.path;
108 }
109 visit[can] = -1;
110 paths[can] = p.path;
111 rque.push(p);
112 }
113 }
114
115 int main() {
116 node_st node, enode;
117 int i, n, can;
118
119 for (i=1; i<N; ++i)
120 enode.map[i-1] = i + ‘0‘;
121 enode.map[N-1] = ‘x‘;
122 enode.xpos = N-1;
123
124 while (scanf("%c%*c", &node.map[0]) != EOF) {
125 for (i=0; i<N; ++i) {
126 if (i)
127 scanf("%c%*c", &node.map[i]);
128 if (node.map[i] == ‘x‘)
129 node.xpos = i;
130 }
131 if ( invNum(node) ) {
132 printf("unsolvable\n");
133 continue;
134 }
135 can = cantor(node);
136 if ( can == 0 ) {
137 printf("\n");
138 continue;
139 }
140 while ( !que.empty() )
141 que.pop();
142 while ( !rque.empty() )
143 rque.pop();
144 memset(visit, 0, sizeof(visit));
145 flag = true;
146 rque.push(enode);
147 visit[0] = -1;
148 que.push(node);
149 visit[can] = 1;
150 while (flag) {
151 n = que.size();
152 while (flag && n--)
153 bfs();
154 n = rque.size();
155 while (flag && n--)
156 rbfs();
157 }
158 cout <<fpath<<endl;
159 }
160
161 return 0;
162 }
时间: 2024-10-08 06:33:51