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