【HDOJ】1043 Eight

这道题目最开始做的时候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-08-01 08:36:23

【HDOJ】1043 Eight的相关文章

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t

【HDOJ】2425 Hiking Trip

优先级队列+BFS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 25 8 9 typedef struct node_st { 10 int x, y, t; 11 node_st() {} 12 node_st(int xx, int yy, int tt)

【HDOJ】1686 Oulipo

kmp算法. 1 #include <cstdio> 2 #include <cstring> 3 4 char src[10005], des[1000005]; 5 int next[10005], total; 6 7 void kmp(char des[], char src[]){ 8 int ld = strlen(des); 9 int ls = strlen(src); 10 int i, j; 11 12 total = i = j = 0; 13 while (

【HDOJ】2795 Billboard

线段树.注意h范围(小于等于n). 1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAXN 200005 5 #define lson l, mid, rt<<1 6 #define rson mid+1, r, rt<<1|1 7 #define mymax(x, y) (x>y) ? x:y 8 9 int nums[MAXN<<2]; 10 int h, w; 11 12