PKU 1324 Holedox Moving
问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1324
参考:
http://hi.baidu.com/aekdycoin/blog/item/08774afbd1a29316a8d31111.html
http://clover520.blogbus.com/logs/38001465.html
思路:
用BFS求最短路径肯定是没有问题的,关键是状态如何表示
参考别人的思路,原来蛇身只需要通过上、下、左、右四个方向表示即可(两bits或4进制),这样可以很大程度上减少空间,而且判重也就不再是个问题,只需要用三维数组表示即可
不过我自己写出来的代码却总是MLE,悲剧...(无奈,贴了别人代码过的,无耻啊)
代码:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1324
参考:
http://hi.baidu.com/aekdycoin/blog/item/08774afbd1a29316a8d31111.html
http://clover520.blogbus.com/logs/38001465.html
思路:
用BFS求最短路径肯定是没有问题的,关键是状态如何表示
参考别人的思路,原来蛇身只需要通过上、下、左、右四个方向表示即可(两bits或4进制),这样可以很大程度上减少空间,而且判重也就不再是个问题,只需要用三维数组表示即可
不过我自己写出来的代码却总是MLE,悲剧...(无奈,贴了别人代码过的,无耻啊)
代码:
1
#include
<
stdio.h
>
2 #include < stdlib.h >
3 #include < string .h >
4
5 int kk[ 4 ][ 2 ] = { 1 , 0 , 0 , 1 , 0 , - 1 , - 1 , 0 },N,M,L;
6 struct point{
7 char x,y;
8 int dis,body;
9 };
10 int bfs();
11 int main(){
12 int Cas = 0 ;
13 while (scanf( " %d%d%d " , & N, & M, & L) == 3 ){
14 if (N == 0 && M == 0 && L == 0 ) break ;
15 printf( " Case %d: %d\n " , ++ Cas,bfs());
16 }
17 return 0 ;
18 }
19 char viss[ 20 ][ 20 ][ 1 << 14 ];
20 int vis( struct point * t){
21 int ans = 0 ,i = 0 ;
22 if (viss[t -> x][t -> y][t -> body]) return 1 ;
23 viss[t -> x][t -> y][t -> body] = 1 ;
24 return 0 ;
25 }
26 char map[ 20 ][ 20 ],mapt[ 20 ][ 20 ];
27 char valid( int x, int y){
28 if (x < 0 || x >= N || y < 0 || y >= M || mapt[x][y]) return 0 ;
29 return 1 ;
30 }
31 struct point Q[ 20 * 20 * ( 1 << 14 )];
32 int head,tail;
33 int bfs(){
34 int x,y,lx,ly,i,k,nx,ny;
35 struct point t,now;
36 memset(viss, 0 , sizeof (viss));
37 scanf( " %d%d " , & lx, & ly);
38 t.x = lx - 1 ;t.y = ly - 1 ;t.dis = 0 ;t.body = 0 ;
39 for (i = 1 ;i < L; ++ i){
40 scanf( " %d%d " , & x, & y);
41 for (k = 0 ;k < 4 ; ++ k) if (lx + kk[k][ 0 ] == x && ly + kk[k][ 1 ] == y) break ;
42 t.body |= k << ((i - 1 ) << 1 );
43 lx = x;ly = y;
44 }
45 memset(map, 0 , sizeof (map));
46 scanf( " %d " , & k);
47 for (i = 0 ;i < k; ++ i){
48 scanf( " %d%d " , & x, & y);
49 map[x - 1 ][y - 1 ] = 1 ;
50 }
51 head = tail = 0 ;
52 Q[tail ++ ] = t;
53 vis( & t);
54 while (head != tail){
55 now = Q[head ++ ];
56 if (now.x == 0 && now.y == 0 ) return now.dis;
57
58 memcpy(mapt,map, sizeof (map));
59 mapt[x = now.x][y = now.y] = 1 ;
60 int s = now.body;
61 for (i = 1 ;i < L; ++ i,s >>= 2 ){
62 k = s & 3 ;
63 mapt[x = x + kk[k][ 0 ]][y = y + kk[k][ 1 ]] = 1 ;
64 }
65
66 for (k = 0 ;k < 4 ; ++ k){
67 if ( ! valid(nx = now.x + kk[k][ 0 ],ny = now.y + kk[k][ 1 ])) continue ;
68 t.x = nx,t.y = ny;
69 t.body = ((now.body << 2 ) | ( 3 - k)) & (( 1 << ((L - 1 ) << 1 )) - 1 );
70 t.dis = now.dis + 1 ;
71 if ( ! vis( & t)){
72 Q[tail ++ ] = t;
73 }
74 }
75 }
76 return - 1 ;
77 }
2 #include < stdlib.h >
3 #include < string .h >
4
5 int kk[ 4 ][ 2 ] = { 1 , 0 , 0 , 1 , 0 , - 1 , - 1 , 0 },N,M,L;
6 struct point{
7 char x,y;
8 int dis,body;
9 };
10 int bfs();
11 int main(){
12 int Cas = 0 ;
13 while (scanf( " %d%d%d " , & N, & M, & L) == 3 ){
14 if (N == 0 && M == 0 && L == 0 ) break ;
15 printf( " Case %d: %d\n " , ++ Cas,bfs());
16 }
17 return 0 ;
18 }
19 char viss[ 20 ][ 20 ][ 1 << 14 ];
20 int vis( struct point * t){
21 int ans = 0 ,i = 0 ;
22 if (viss[t -> x][t -> y][t -> body]) return 1 ;
23 viss[t -> x][t -> y][t -> body] = 1 ;
24 return 0 ;
25 }
26 char map[ 20 ][ 20 ],mapt[ 20 ][ 20 ];
27 char valid( int x, int y){
28 if (x < 0 || x >= N || y < 0 || y >= M || mapt[x][y]) return 0 ;
29 return 1 ;
30 }
31 struct point Q[ 20 * 20 * ( 1 << 14 )];
32 int head,tail;
33 int bfs(){
34 int x,y,lx,ly,i,k,nx,ny;
35 struct point t,now;
36 memset(viss, 0 , sizeof (viss));
37 scanf( " %d%d " , & lx, & ly);
38 t.x = lx - 1 ;t.y = ly - 1 ;t.dis = 0 ;t.body = 0 ;
39 for (i = 1 ;i < L; ++ i){
40 scanf( " %d%d " , & x, & y);
41 for (k = 0 ;k < 4 ; ++ k) if (lx + kk[k][ 0 ] == x && ly + kk[k][ 1 ] == y) break ;
42 t.body |= k << ((i - 1 ) << 1 );
43 lx = x;ly = y;
44 }
45 memset(map, 0 , sizeof (map));
46 scanf( " %d " , & k);
47 for (i = 0 ;i < k; ++ i){
48 scanf( " %d%d " , & x, & y);
49 map[x - 1 ][y - 1 ] = 1 ;
50 }
51 head = tail = 0 ;
52 Q[tail ++ ] = t;
53 vis( & t);
54 while (head != tail){
55 now = Q[head ++ ];
56 if (now.x == 0 && now.y == 0 ) return now.dis;
57
58 memcpy(mapt,map, sizeof (map));
59 mapt[x = now.x][y = now.y] = 1 ;
60 int s = now.body;
61 for (i = 1 ;i < L; ++ i,s >>= 2 ){
62 k = s & 3 ;
63 mapt[x = x + kk[k][ 0 ]][y = y + kk[k][ 1 ]] = 1 ;
64 }
65
66 for (k = 0 ;k < 4 ; ++ k){
67 if ( ! valid(nx = now.x + kk[k][ 0 ],ny = now.y + kk[k][ 1 ])) continue ;
68 t.x = nx,t.y = ny;
69 t.body = ((now.body << 2 ) | ( 3 - k)) & (( 1 << ((L - 1 ) << 1 )) - 1 );
70 t.dis = now.dis + 1 ;
71 if ( ! vis( & t)){
72 Q[tail ++ ] = t;
73 }
74 }
75 }
76 return - 1 ;
77 }