hdu 1041 Solitaire

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1068    Accepted Submission(s): 344

        本题对本人来说是个挑战,花费了一天的时间,总算搞定,本题的思想就是 双向BFS+MAP+位压缩存储。声明两个队列,分别表示正向搜索,和反向搜索,再声明两个MAP分别存储两个队列搜索过的状态,由于本题有8行8列,所以用位压缩来存储状态,用unsigned __int64整数表示(__int64位恐怕不行)。两个MAP有两个作用:

第一:当当前队列在本MAP中找到相同状态时表示已经搜过,不用再搜;

第二:当当前队列在对方MAP中找到相同状态时表示找到,可以到达;

代码:  

 

  
    
1 #include < stdio.h >
2 #include < math.h >
3 #include < map >
4 #include < queue >
5 using namespace std;
6 typedef struct node
7 {
8 int x,y;
9 }NODE;
10 typedef struct m
11 {
12 NODE s[ 4 ];
13 int time;
14 }MAP;
15 int main()
16 {
17 map < unsigned __int64, int > m1;
18 map < unsigned __int64, int > m2;
19 queue < MAP > qu1,qu2;
20 MAP cur1,cur2,next1,next2;
21 unsigned __int64 s;
22 int sx,sy,ex,ey,i,j,k,mark,map1[ 9 ][ 9 ];
23 int dir[ 4 ][ 2 ] = {{ 1 , 0 },{ - 1 , 0 },{ 0 , 1 },{ 0 , - 1 }};
24 while (scanf( " %d%d " , & sx, & sy) != EOF)
25 {
26 m1.clear ();
27 m2.clear ();
28 while ( ! qu1.empty ())
29 qu1.pop();
30 while ( ! qu2.empty ())
31 qu2.pop();
32 s = 0 ;mark = 0 ;
33 cur1.s[ 0 ].x = sx;
34 cur1.s[ 0 ].y = sy;
35 s += (unsigned __int64)pow( 2.0 ,( int )((sx - 1 ) * 8 + sy - 1 ));
36 for (i = 1 ;i <= 3 ;i ++ )
37 {
38 scanf( " %d%d " , & sx, & sy);
39 cur1.s[i].x = sx;
40 cur1.s[i].y = sy;
41 s += (unsigned __int64)pow( 2.0 ,( int )((sx - 1 ) * 8 + sy - 1 ));
42 }
43 cur1.time = 0 ;
44 m1[s] = cur1.time;
45 qu1.push(cur1);
46 s = 0 ;
47 for (i = 0 ;i < 4 ;i ++ )
48 {
49 scanf( " %d%d " , & ex, & ey);
50 cur2.s[i].x = ex;
51 cur2.s[i].y = ey;
52 s += (unsigned __int64)pow( 2.0 ,((ex - 1 ) * 8 + ey - 1 ));
53 }
54 cur2.time = 0 ;
55 map < unsigned __int64, int > ::iterator it;
56 it = m1.find(s);
57 if (it != m1.end())
58 {
59 printf( " YES\n " );
60 continue ;
61 }
62 m2[s] = cur2.time;
63 qu2.push(cur2);
64 while ( ! qu1.empty() || ! qu2.empty ())
65 {
66 if ( ! qu2.empty() && (qu1.size () >= qu2.size () || qu1.empty ()))
67 {
68 cur2 = qu2.front();
69 while ( ! qu2.empty() && cur2.time > 4 )
70 {
71 qu2.pop();
72 cur2 = qu2.front ();
73 }
74 qu2.pop();
75 s = 0 ;
76 for (i = 0 ;i < 4 ;i ++ )
77 {
78 s += (unsigned __int64)pow( 2.0 ,((cur2.s[i].x - 1 ) * 8 + cur2.s[i].y - 1 ));
79 }
80 it = m1.find(s);
81 if (it != m1.end() )
82 {
83 if (( * it).second + cur2.time <= 8 )
84 {
85 mark = 1 ;
86 break ;
87 }
88 else
89 continue ;
90 }
91 memset(map1, 0 , sizeof (map1));
92 for (i = 0 ;i < 4 ;i ++ )
93 {
94 map1[cur2.s[i].x][cur2.s[i].y] = 1 ;
95 }
96 for (i = 0 ;i < 4 ;i ++ )
97 {
98 next2 = cur2;
99 sx = cur2.s[i].x;
100 sy = cur2.s[i].y;
101 for (j = 0 ;j < 4 ;j ++ )
102 {
103 ex = sx + dir[j][ 0 ];
104 ey = sy + dir[j][ 1 ];
105 if (ex >= 1 && ex <= 8 && ey >= 1 && ey <= 8 && map1[ex][ey] == 1 )
106 {
107 ex = sx + 2 * dir[j][ 0 ];
108 ey = sy + 2 * dir[j][ 1 ];
109 }
110 if (ex >= 1 && ex <= 8 && ey >= 1 && ey <= 8 && map1[ex][ey] == 0 )
111 {
112 s = 0 ;
113 next2.s[i].x = ex;
114 next2.s[i].y = ey;
115 for (k = 0 ;k < 4 ;k ++ )
116 {
117 s += (unsigned __int64)pow( 2.0 ,((next2.s[k].x - 1 ) * 8 + next2.s[k].y - 1 ));
118 }
119 it = m2.find(s);
120 next2.time = cur2.time + 1 ;
121 if (next2.time > 4 )
122 continue ;
123 if (it != m2.end() && ( * it).second <= next2.time)
124 continue ;
125 m2[s] = next2.time;
126 qu2.push(next2);
127 }
128 }
129 }
130 }
131 else
132 {
133 cur1 = qu1.front ();
134 while ( ! qu1.empty () && cur1.time > 4 )
135 {
136 qu1.pop();
137 cur1 = qu1.front ();
138 }
139 qu1.pop();
140 s = 0 ;
141 for (i = 0 ;i < 4 ;i ++ )
142 {
143 s += (unsigned __int64)pow( 2.0 ,((cur1.s[i].x - 1 ) * 8 + cur1.s[i].y - 1 ));
144 }
145 it = m2.find(s);
146 if (it != m2.end())
147 {
148 if (( * it).second + cur1.time <= 8 )
149 {
150 mark = 1 ;
151 break ;
152 }
153 else
154 continue ;
155 }
156 memset(map1, 0 , sizeof (map1));
157 for (i = 0 ;i < 4 ;i ++ )
158 {
159 map1[cur1.s[i].x][cur1.s[i].y] = 1 ;
160 }
161 for (i = 0 ;i < 4 ;i ++ )
162 {
163 next1 = cur1;
164 sx = cur1.s[i].x;
165 sy = cur1.s[i].y;
166 for (j = 0 ;j < 4 ;j ++ )
167 {
168 ex = sx + dir[j][ 0 ];
169 ey = sy + dir[j][ 1 ];
170 if (ex >= 1 && ex <= 8 && ey >= 1 && ey <= 8 && map1[ex][ey] == 1 )
171 {
172 ex = sx + 2 * dir[j][ 0 ];
173 ey = sy + 2 * dir[j][ 1 ];
174 }
175 if (ex >= 1 && ex <= 8 && ey >= 1 && ey <= 8 && map1[ex][ey] == 0 )
176 {
177 s = 0 ;
178 next1.s[i].x = ex;
179 next1.s[i].y = ey;
180 for (k = 0 ;k < 4 ;k ++ )
181 {
182 s += (unsigned __int64)pow( 2.0 ,((next1.s[k].x - 1 ) * 8 + next1.s[k].y - 1 ));
183 }
184 it = m1.find(s);
185 next1.time = cur1.time + 1 ;
186 if (next1.time > 4 )
187 continue ;
188 if (it != m1.end() && ( * it).second <= next1.time)
189 continue ;
190 m1[s] = next1.time ;
191 qu1.push(next1);
192 }
193 }
194 }
195 }
196 }
197 if (mark)
198 printf( " YES\n " );
199 else
200 printf( " NO\n " );
201 }
202 return 0 ;
203 }
204

 测试数据:

 

  
    
1 4 3 7 4 5 6 2
1 4 3 7 4 5 6 2
// YES
2 1 8 8 7 8 1 1
1 5 8 7 7 7 2 4
// YES
6 5 5 7 5 1 7 1
7 7 6 5 5 7 6 3
// YES
4 6 5 6 5 5 5 2
2 2 7 6 5 3 5 2
// YES
4 4 5 5 3 4 7 2
2 7 7 2 6 5 4 8
// YES
4 2 3 4 5 5 6 6
2 7 4 4 3 5 4 5
// YES
3 3 5 3 6 2 6 6
6 3 8 3 6 6 6 8
// YES
3 2 5 3 6 2 6 6
6 3 8 3 6 6 6 8
// NO
3 4 4 5 5 5 7 5
3 3 4 3 5 3 6 3
// YES

 

你可能感兴趣的:(AIR)