A Za, A Za, Fighting...

坚信:勤能补拙

PKU 1198 Solitaire

问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1198

思路:
宽度优先搜索
tips:
1. 如何表示整个chessboard?
   最简单的方法是用二维数组,不过如果发现该chessboard是8X8的话,很自然地会想到是否可以用一个整数来表示
   答案是肯定的,long long类型,不过可能unsigned long long会更合适,避免负数产生的影响呵呵

2. 如何判断一个状态是否被访问过?
   根据tips 1,我们使用一个unsigned long long来表示状态,而如果用一个一维数组来表示其整个范围显然是不合适的
   答案是利用HASH表,额...不是我自己想的,不过这个想法我是应该想到的,艾...继续加油
   HASH, 相当强大而简单的方案
   这里我是使用链接法来解决HASH冲突的

单向宽度优先搜索
刚提交的时候一直TLE, 结果我将HASH_MAX设置地更大之后,勉勉强强地通过了,汗...
 1 #define BOARD 8
 2 #define MOVE_MAX 8
 3 #define PRIME 100007
 4 #define HASH_MAX PRIME
 5 #define is_set(i, j, state) (state & (((unsigned long long)1)<<((i)*BOARD+(j))))
 6 #define set_bit(i, j, state) (state |= (((unsigned long long)1)<<((i)*BOARD+(j))))
 7 #define clear_bit(i, j, state) (state &= (~(((unsigned long long)1)<<((i)*BOARD+(j)))))
 8 #define is_valid(i, j) (i>=0 && i<BOARD && j>=0 && j<BOARD)
 9 struct Node {
10     /* 8x8 chessboard can be represented by 64 bits */
11     unsigned long long state;
12     short move;
13 }queue[635376];
14 unsigned long long begin, end;
15 const int dx[] = {00-11};
16 const int dy[] = {-1100};
17 int head, tail;
18 struct Hash {
19     unsigned long long *pstate;
20     struct Hash *next;
21 }hash_table[HASH_MAX];
22 
23 int
24 check_hash(unsigned long long value)
25 {
26     int index = value % PRIME;
27     struct Hash *= hash_table[index].next;
28     while(p != NULL) {
29         if(*(p->pstate) == value) 
30             return 1;
31         p = p->next;
32     }
33     return 0;
34 }
35 
36 void
37 insert_hash(unsigned long long *pstate, int index)
38 {
39     struct Hash *node = malloc(sizeof(struct Hash));
40     node->pstate = pstate;
41     node->next = hash_table[index].next;
42     hash_table[index].next = node;
43 }
44 
45 int
46 bfs()
47 {
48     int i, j, x, y, next_x, next_y, cnt, cur_move=0;
49     unsigned long long cur_state, next_state;
50     queue[tail].state = begin;
51     queue[tail].move = 0;
52     insert_hash(&(queue[tail].state), (queue[tail].state)%PRIME);
53     while(head<tail && cur_move<=MOVE_MAX) {
54         ++head;
55         cnt = 0;
56         cur_state = queue[head].state;
57         cur_move = queue[head].move;
58         if(cur_state == end)
59             return 1;
60         for(i=0; i<64 && cnt<4; i++) {
61             if(cur_state & (((unsigned long long)1)<<i)) {
62                 ++cnt;
63                 x = i/BOARD;
64                 y = i%BOARD; 
65                 for(j=0; j<4; j++) { /* left, right, up, down */
66                     next_x = x + dx[j];
67                     next_y = y + dy[j];
68                     if(!is_valid(next_x, next_y))
69                         continue;
70                     if(is_set(next_x, next_y, cur_state)) {
71                         next_x += dx[j];
72                         next_y += dy[j];
73                         if(!is_valid(next_x, next_y))
74                             continue;
75                     }
76                     /* make sure the next state never showed before */
77                     /* hash: one of the most powerful tools */
78                     next_state = cur_state;
79                     clear_bit(x, y, next_state);
80                     set_bit(next_x, next_y, next_state);
81                     if(!check_hash(next_state)) {
82                         ++tail;
83                         queue[tail].move = cur_move + 1;
84                         queue[tail].state = next_state;
85                         insert_hash(&(queue[tail].state), (queue[tail].state)%PRIME);
86                     } 
87                 }
88             }
89         }
90     }
91     return 0;
92 }

双向宽度优先搜索
当我们知道开始和结束状态的条件下,可以采用双向宽度优先搜索
而且可以大大减小需要搜索的状态数目,因为需要搜索的层数减少一半
  1 /* bidirectional BFS */
  2 /* Memory: 2704K Time: 47MS */
  3 #include<stdio.h>
  4 #include<stdlib.h>
  5 #include<string.h>
  6 
  7 #define BOARD 8
  8 #define MOVE_MAX 8
  9 #define PRIME 10007
 10 #define HASH_MAX PRIME
 11 #define is_set(i, j, state) (state & (((unsigned long long)1)<<((i)*BOARD+(j))))
 12 #define set_bit(i, j, state) (state |= (((unsigned long long)1)<<((i)*BOARD+(j))))
 13 #define clear_bit(i, j, state) (state &= (~(((unsigned long long)1)<<((i)*BOARD+(j)))))
 14 #define is_valid(i, j) (i>=0 && i<BOARD && j>=0 && j<BOARD)
 15 struct Node {
 16     /* 8x8 chessboard can be represented by 64 bits */
 17     unsigned long long state;
 18     short move;
 19 }queue[63537], second_queue[63537];
 20 unsigned long long begin, end;
 21 const int dx[] = {00-11};
 22 const int dy[] = {-1100};
 23 int head, tail, second_head, second_tail;
 24 struct Hash {
 25     unsigned long long *pstate;
 26     struct Hash *next;
 27 }hash_table[HASH_MAX], second_hash_table[HASH_MAX];
 28 
 29 int
 30 check_hash(struct Hash *hash, unsigned long long value)
 31 {
 32     int index = value % PRIME;
 33     struct Hash *= hash[index].next;
 34     while(p != NULL) {
 35         if(*(p->pstate) == value) 
 36             return 1;
 37         p = p->next;
 38     }
 39     return 0;
 40 }
 41 
 42 void
 43 insert_hash(struct Hash *hash, unsigned long long *pstate, int index)
 44 {
 45     struct Hash *node = malloc(sizeof(struct Hash));
 46     node->pstate = pstate;
 47     node->next = hash[index].next;
 48     hash[index].next = node;
 49 }
 50 
 51 int
 52 bfs()
 53 {
 54     int i, j, x, y, next_x, next_y, cnt, cur_move, second_cur_move;
 55     cur_move = second_cur_move = 0;
 56     unsigned long long cur_state, next_state;
 57     queue[tail].state = begin;
 58     queue[tail].move = 0;
 59     insert_hash(hash_table, &(queue[tail].state), (queue[tail].state)%PRIME);
 60     second_queue[second_tail].state = end;
 61     second_queue[second_tail].move = 0;
 62     insert_hash(second_hash_table, &(second_queue[second_tail].state), (second_queue[second_tail].state)%PRIME);
 63     while(head<tail && second_head<second_tail) {
 64         ++head;
 65         cnt = 0;
 66         cur_state = queue[head].state;
 67         cur_move = queue[head].move;
 68         for(i=0; i<64 && cnt<4; i++) {
 69             if(cur_state & (((unsigned long long)1)<<i)) {
 70                 ++cnt;
 71                 x = i/BOARD;
 72                 y = i%BOARD; 
 73                 for(j=0; j<4; j++) { /* left, right, up, down */
 74                     next_x = x + dx[j];
 75                     next_y = y + dy[j];
 76                     if(!is_valid(next_x, next_y))
 77                         continue;
 78                     if(is_set(next_x, next_y, cur_state)) {
 79                         next_x += dx[j];
 80                         next_y += dy[j];
 81                         if(!is_valid(next_x, next_y))
 82                             continue;
 83                     }
 84                     /* make sure the next state never showed before */
 85                     /* hash: one of the most powerful tools */
 86                     next_state = cur_state;
 87                     clear_bit(x, y, next_state);
 88                     set_bit(next_x, next_y, next_state);
 89                     if(!check_hash(hash_table, next_state) && cur_move<MOVE_MAX/2) {
 90                         if(check_hash(second_hash_table, next_state)) 
 91                             return 1;
 92                         ++tail;
 93                         queue[tail].move = cur_move + 1;
 94                         queue[tail].state = next_state;
 95                         insert_hash(hash_table, &(queue[tail].state), (queue[tail].state)%PRIME);
 96                     } 
 97                 }
 98             }
 99         }
100         ++second_head;
101         cnt = 0;
102         cur_state = second_queue[second_head].state;
103         second_cur_move = second_queue[second_head].move;
104         for(i=0; i<64 && cnt<4; i++) {
105             if(cur_state & (((unsigned long long)1)<<i)) {
106                 ++cnt;
107                 x = i/BOARD;
108                 y = i%BOARD; 
109                 for(j=0; j<4; j++) {
110                     next_x = x + dx[j];
111                     next_y = y + dy[j];
112                     if(!is_valid(next_x, next_y))
113                         continue;
114                     if(is_set(next_x, next_y, cur_state)) {
115                         next_x += dx[j];
116                         next_y += dy[j];
117                         if(!is_valid(next_x, next_y))
118                             continue;
119                     }
120                     next_state = cur_state;
121                     clear_bit(x, y, next_state);
122                     set_bit(next_x, next_y, next_state);
123                     if(!check_hash(second_hash_table, next_state) && second_cur_move<MOVE_MAX/2) {
124                         if(check_hash(hash_table, next_state)) 
125                             return 1;
126                         ++second_tail;
127                         second_queue[second_tail].move = second_cur_move + 1;
128                         second_queue[second_tail].state = next_state;
129                         insert_hash(second_hash_table, &(second_queue[second_tail].state), (second_queue[second_tail].state)%PRIME);
130                     } 
131                 }
132             }
133         }
134     }
135     return 0;
136 }
137 
138 int
139 main(int argc, char **argv)
140 {
141     int i, j, k;
142     while(scanf("%d %d"&i, &j) != EOF) {
143         head = second_head = -1;
144         tail = second_tail = 0;
145         begin = end = 0;
146         set_bit(i-1, j-1, begin);
147         memset(hash_table, 0sizeof(hash_table));
148         memset(second_hash_table, 0sizeof(second_hash_table));
149         memset(queue, 0sizeof(queue));
150         memset(second_queue, 0sizeof(second_queue));
151         for(k=1; k<4; k++) {
152             scanf("%d %d"&i, &j);
153             set_bit(i-1, j-1, begin);
154         }
155         for(k=0; k<4; k++) {
156             scanf("%d %d"&i, &j);
157             set_bit(i-1, j-1, end);
158         }
159         printf("%s\n", bfs()==1 ? "YES" : "NO");
160     }
161 }


posted on 2010-07-05 11:56 simplyzhao 阅读(171) 评论(0)  编辑 收藏 引用 所属分类: B_搜索


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


导航

<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜