UVA 10085 - The most distant state

连接戳我.

这是一道隐式图搜索的题目. 八式图的拓展. 方法是BFS + Hash Table.

The most distant指的是:从开始状态到其他所有状态的最短走法里面最长的。

WA了.

View Code
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 
  6 typedef int State[9];
  7 const int MAXSTATE = 1000000;
  8 const int MAXHASHSIZE = 100000;
  9 
 10 State st[MAXSTATE];
 11 int paren[MAXSTATE];
 12 char dir[MAXSTATE];
 13 int head[MAXHASHSIZE], next[MAXSTATE];
 14 
 15 // Up, down, left, right
 16 const int dx[] = {-1, 1, 0, 0};
 17 const int dy[] = {0, 0, -1, 1};
 18 const char direction[] = {'U', 'D', 'L', 'R'};
 19 
 20 void init_lookup_table() {
 21     memset(head, 0, sizeof(head));
 22     memset(next, 0, sizeof(next));
 23 }
 24 
 25 int hash(State& s) {
 26     int v = 0;
 27     for (int i = 0; i < 9; i++){
 28         v = v*10 + s[i];
 29     }
 30     return v % MAXHASHSIZE;
 31 }
 32 
 33 bool try_to_insert(int s) {
 34     int h = hash(st[s]);
 35     int u = head[h];
 36     while (u){
 37         if (memcmp(st[u], st[s], sizeof(st[s])) == 0)
 38             return false;
 39         u = next[u];
 40     }
 41     next[s] = head[h];
 42     head[h] = s;
 43     return true;
 44 }
 45 
 46 int bfs(){
 47     init_lookup_table();
 48     try_to_insert(1);
 49 
 50     int front = 1, rear = 2;
 51     while (front < rear){
 52         State& s = st[front];
 53 
 54         int z = 0;
 55         while (s[z])
 56             z++;
 57 
 58         int x = z/3, y = z%3;
 59         for (int i = 0; i < 4; i++){
 60             int newx = x + dx[i];
 61             int newy = y + dy[i];
 62             int newz = newx*3 + newy;
 63 
 64             if (newx >= 0 && newx < 3 && newy >= 0 && newy < 3){
 65                 State&t = st[rear];
 66                 memcpy(&t, &s, sizeof(s));
 67 
 68                 paren[rear] = front;
 69                 dir[rear] = direction[i];
 70                 t[newz] = s[z];
 71                 t[z] = s[newz];
 72 
 73                 if (try_to_insert(rear)){
 74                     rear++;
 75                 }
 76             }
 77         }
 78         front++;
 79     }
 80     return rear-1;
 81 }
 82 
 83 
 84 int main(int argc, char *argv[]){
 85     int cases;
 86     const int MAXLENGTH = 100;
 87     char ch[MAXLENGTH];
 88     cin.getline(ch, MAXLENGTH);
 89     cases = ch[0] - '0';
 90     cin.getline(ch, MAXLENGTH);
 91 
 92     int counter = 1;
 93     while (counter <= cases){
 94         memset(st, 0, sizeof(st));
 95         memset(dir, 0, sizeof(dir));
 96         memset(paren, 0, sizeof(paren));
 97 
 98         for (int i = 0; i < 9; i++){
 99             cin >> st[1][i];
100         }
101 
102         int ans = bfs();
103         cout << "Puzzle #" << counter << endl;
104         for (int i = 0; i < 3; i++){
105             printf("%d %d %d",
106                    st[ans][i*3], st[ans][i*3+1], st[ans][i*3+2]);
107             cout << endl;
108         }
109 
110         char move[1000];
111         int temp = ans, length = 0;
112         while (temp != 1){
113             move[length++] = dir[temp];
114             temp = paren[temp];
115         }
116         for (int i = length-1; i >= 0; i--){
117             cout << move[i];
118         }
119         cout << endl;
120 
121         cout << endl;
122         counter++;
123     }
124     return 0;
125 }

 

posted @ 2013-02-12 22:35  frankdj  阅读(192)  评论(0编辑  收藏  举报