hdu1515
深搜能过,想好搜索技巧,很容易过。
题意:给你两个字符串,问:第一个字符串按入栈出栈规则,能否达到第二个字符串,输出所有的方法,i表示入栈,o表示出栈。
用dfs模拟第一个字符串入栈出栈过程:
1. 当前字符入栈,就向下一层递归,即搜向下一个字符
2. 栈顶元素出栈,对新的栈顶元素判断
这题要求按字典序输出,这种先判断入,再判断出的方法正好符合。
2 #include < string .h >
3 int len1, len2;
4 char stack[ 200 ];
5 char s1[ 100 ], s2[ 100 ];
6 char ans[ 200 ];
7 void dfs( int cur, int top, int idx, int step){
8 int i, t, tmp;
9 if (idx == len2){
10 for (i = 0 ; i < step; i ++ ){
11 printf( " %c " , ans[i]);
12 }
13 puts( "" );
14 return ;
15 }
16 if (cur < len1){
17 t = top + 1 ;
18 tmp = stack[t]; // 将栈中元素暂存
19 stack[t] = s1[cur];
20 ans[step] = ' i ' ;
21 dfs(cur + 1 , t, idx, step + 1 );
22 stack[t] = tmp; // 把栈中元素恢复
23 }
24 if (top == - 1 ) return ;
25 if (stack[top] == s2[idx]){
26 ans[step] = ' o ' ;
27 t = top - 1 ;
28 dfs(cur, t, idx + 1 , step + 1 );
29 }
30 }
31 int main()
32 {
33 while (scanf( " %s%s " , s1, s2) != EOF){
34 len1 = strlen(s1);
35 len2 = strlen(s2);
36 if (len1 < len2){
37 printf( " [\n]\n " );
38 continue ;
39 }
40 puts( " [ " );
41 dfs( 0 , - 1 , 0 , 0 );
42 puts( " ] " );
43 }
44 return 0 ;
45 }
46
hdu1401
题意:在8 * 8 的跳棋棋盘上,给你两个状态,每个状态4个点,判断一个状态8步内能否到达另一个状态。
解法:广搜。每个状态4个棋子,每个棋子一步有4种走法,就是说,一个状态有16个后继状态,为了节省空间,用双向BFS,两个状态同时入队,交替着搜,各搜4步,判断有没有可能到达,我这里为了省便,初状态先搜了4步,将所有状态用二进制压缩成一个整数,用set容器存下来,再由终点状态搜4步,判断能不能到达由起点状态到达的任一状态,从而判断能否两个状态8步以内转换。
2 #include < stdlib.h >
3 #include < set >
4 using namespace std;
5 int ok;
6 unsigned __int64 ans;
7 int dir[ 4 ][ 2 ] = { 0 , 1 , 1 , 0 , - 1 , 0 , 0 , - 1 };
8 typedef struct node{
9 int x[ 5 ];
10 int y[ 5 ];
11 int n;
12 }NODE;
13
14 NODE sta, end, que[ 106540 ];
15 set < unsigned __int64 > se;
16 int Judge( int x[], int y[], int nxtx, int nxty, int i){
17 int k;
18 for (k = 0 ; k < 4 ; k ++ ){
19 if (k == i){
20 continue ;
21 }
22 if (x[k] == nxtx && y[k] == nxty){
23 return 0 ;
24 }
25 }
26 return 1 ;
27 }
28
29 void putin(NODE a){
30 int i;
31 ans = 0 ;
32 for (i = 0 ; i < 4 ; i ++ ){
33 ans += (unsigned __int64) 1 << ((a.x[i] - 1 ) * 8 + a.y[i] - 1 );
34 }
35 se.insert(ans);
36 }
37 void bfs1(){
38 NODE cur, nxt;
39 que[ 0 ] = sta;
40
41 int head, tail, i, j, t1, t2, k;
42 putin(sta);
43 head = tail = 0 ;
44 while (head <= tail){
45 cur = que[head ++ ];
46 /* for (k = 0; k < 4; k++){
47 printf("%d %d ", cur.x[k], cur.y[k]);
48 } */
49 for (i = 0 ; i < 4 ; i ++ ){
50
51 for (j = 0 ; j < 4 ; j ++ ){
52 nxt = cur;
53 nxt.n = cur.n + 1 ;
54 if (nxt.n > 4 ) return ;
55 nxt.x[j] = dir[i][ 0 ] + cur.x[j];
56 nxt.y[j] = dir[i][ 1 ] + cur.y[j];
57 if (nxt.x[j] >= 1 && nxt.x[j] <= 8 && nxt.y[j] >= 1 && nxt.y[j] <= 8 ){
58 if (Judge(cur.x, cur.y, nxt.x[j], nxt.y[j], j)){
59 t1 = se.size();
60 putin(nxt);
61 t2 = se.size();
62 if (t1 != t2){
63 que[ ++ tail] = nxt;
64 }
65 } else {
66 nxt.x[j] = dir[i][ 0 ] + nxt.x[j];
67 nxt.y[j] = dir[i][ 1 ] + nxt.y[j];
68 if (nxt.x[j] >= 1 && nxt.x[j] <= 8 && nxt.y[j] >= 1 && nxt.y[j] <= 8 ){
69 if (Judge(cur.x, cur.y, nxt.x[j], nxt.y[j], j)){
70 t1 = se.size();
71 putin(nxt);
72 t2 = se.size();
73 if (t1 != t2){
74 que[ ++ tail] = nxt;
75 }
76 }
77 }
78 }
79 }
80 }
81 }
82 }
83 }
84
85 void bfs2(){
86 NODE cur, nxt;
87 que[ 0 ] = end;
88
89 int head, tail, i, j, t1, t2;
90 t1 = se.size();
91 putin(end);
92 t2 = se.size();
93 if (t1 == t2){
94 ok = 1 ;
95 return ;
96 }
97 se.erase(ans);
98 head = tail = 0 ;
99 while (head <= tail){
100 cur = que[head ++ ];
101 for (i = 0 ; i < 4 ; i ++ ){
104 for (j = 0 ; j < 4 ; j ++ ){
105 nxt = cur;
106 nxt.n = cur.n + 1 ; if (nxt.n > 4 ) return ;
107 nxt.x[j] = dir[i][ 0 ] + cur.x[j];
108 nxt.y[j] = dir[i][ 1 ] + cur.y[j];
109 if (nxt.x[j] >= 1 && nxt.x[j] <= 8 && nxt.y[j] >= 1 && nxt.y[j] <= 8 ){
110 if (Judge(cur.x, cur.y, nxt.x[j], nxt.y[j], j)){
111 que[ ++ tail] = nxt;
112 t1 = se.size();
113 putin(nxt);
114 t2 = se.size();
115 if (t1 == t2){
116 ok = 1 ;
117 return ;
118 }
119 se.erase(ans);
120 } else {
121 nxt.x[j] = dir[i][ 0 ] + nxt.x[j];
122 nxt.y[j] = dir[i][ 1 ] + nxt.y[j];
123 if (nxt.x[j] >= 1 && nxt.x[j] <= 8 && nxt.y[j] >= 1 && nxt.y[j] <= 8 ){
124 if (Judge(cur.x, cur.y, nxt.x[j], nxt.y[j], j)){
125 que[ ++ tail] = nxt;
126 t1 = se.size();
127 putin(nxt);
128 t2 = se.size();
129 if (t1 == t2){
130 ok = 1 ;
131 return ;
132 }
133 se.erase(ans);
134 }
135 }
136 }
137 }
138 }
139 }
140 }
141 }
142 int main()
143 {
144 int i;
145 while (scanf( " %d%d " , & sta.x[ 0 ], & sta.y[ 0 ]) != EOF){
146 for (i = 1 ; i <= 3 ; i ++ ){
147 scanf( " %d%d " , & sta.x[i], & sta.y[i]);
148 }
149 sta.n = 0 ;
150 for (i = 0 ; i <= 3 ; i ++ ){
151 scanf( " %d%d " , & end.x[i], & end.y[i]);
152 }
153 end.n = 0 ;
154 ok = 0 ;
155 bfs1();
156 bfs2();
157 if (ok) puts( " YES " );
158 else puts( " NO " );
159 se.clear();
160 }
161 return 0 ;
162 }
163
代码重复性很高,可以稍作处理,减少代码量。这里用set判重,如果set的大小没变,说明加入的值已存在。
加几组数据:
1 4 3 7 4 5 6 2 1 4 3 7 4 5 6 2
2 1 8 8 7 8 1 1 1 5 8 7 7 7 2 4
6 5 5 7 5 1 7 1 7 7 6 5 5 7 6 3
4 6 5 6 5 5 5 2 2 2 7 6 5 3 5 2
4 4 5 5 3 4 7 2 2 7 7 2 6 5 4 8
4 2 3 4 5 5 6 6 2 7 4 4 3 5 4 5
3 3 5 3 6 2 6 6 6 3 8 3 6 6 6 8
3 2 5 3 6 2 6 6 6 3 8 3 6 6 6 8
3 4 4 5 5 5 7 5 3 3 4 3 5 3 6 3
解为:
YES
YES
YES
YES
YES
YES
YES
NO
YES