eight - zoj 1217 poj 1077

学习了多位大牛的方法,看看到底能把时耗降到多少?

A*

  1 // zojfulltest: 30000ms
  2 # include <stdio.h>
  3 # include <ctype.h>
  4 # include <stdlib.h>
  5 # include <string.h>
  6 
  7 # define DATA(x,i) (((x)>>((i)*3))&0x7)
  8 # define ZERO(x) ((x)>>27)
  9 # define F(x) ((x)&0xFF)
 10 # define D(x) (((x)>>8)&0xF)
 11 # define P(x) ((x)>>12)
 12 # define MAKE(f,d,p) ((f)|((d)<<8)|((p)<<12))
 13 # define LESS(x,y) (((x)-(y))>>31)
 14 # define SWP(i,j,t) (((t)<<(3*(i)))-((t)<<(3*(j)))+((j)<<27)-((i)<<27))
 15 
 16 const unsigned int maxd = 35;
 17 //dest: 0100 0000 0001 1111 0101 1000 1101 0001
 18 const unsigned int dest = 0x401F58D1;
 19 const unsigned int hashmod = 10007;
 20 const unsigned int maxnode = 0x1<<15;
 21 const unsigned int maxsize = 0x1<<13;
 22 const int mv[][4] = {{-1,-1,1, 3},{-1,0,2, 4},{-1,1,-1, 5},
 23     { 0,-1,4, 6},{ 1,3,5, 7},{ 2,4,-1, 8},
 24     { 3,-1,7,-1},{ 4,6,8,-1},{ 5,7,-1,-1}};
 25 const char mvs[] = "ulrd";
 26 
 27 struct state {
 28     unsigned int u, v;
 29 };
 30 state a[maxnode], child;
 31 unsigned int src, depth, totnode, h[9][9], t[9];
 32 unsigned int head[hashmod], next[maxnode];
 33 unsigned int hp[maxsize], hps;
 34 unsigned int stk[maxsize], top;
 35 
 36 void init(void)
 37 {
 38     memset(h, 0, sizeof(h));
 39     for (int j, i = 1; i != 9; ++i) {
 40         for (j = 0; j != 9; ++j) {
 41             h[i][j] = abs(j/3-(i-1)/3)+abs(j%3-(i-1)%3);
 42         }
 43     }
 44     for (int i = 0; i != 9; ++i) {
 45         h[0][i] = h[8][i];
 46     }
 47 }
 48 bool read_src(void)
 49 {
 50     src = 0;
 51     for (int ch, i = 0; i != 9; ) {
 52         ch = getchar();
 53         if (isdigit(ch)) t[i++] = ch-'0';
 54         else if (ch == 'x') {
 55             t[i] = 0;
 56             src |= ((i++)<<27);
 57         } else if (ch == EOF) return false;
 58     }
 59     for (int i = 0; i != 9; ++i)  src |= ((t[i]&0x7)<<(3*i));
 60     return true;
 61 }
 62 bool no_answer(void)
 63 {
 64     int inv = -ZERO(src), i, j;
 65     for (i = 0; i != 8; ++i) {
 66         for (j = i+1; j != 9; ++j) {
 67             inv += LESS(t[j],t[i]);
 68         }
 69     }
 70     return ((inv)&0x1);
 71 }
 72 void print_sol(int ID)
 73 {
 74     if (ID == 1) return ;
 75     print_sol(P(a[ID].v));
 76     putchar( mvs[D(a[ID].v)] );
 77 }
 78 void addnode(void)
 79 {
 80     int k = child.u % hashmod;
 81     for (int w = head[k]; w ; w = next[w]) {
 82         if (a[w].u == child.u) {
 83             if ( LESS(F(child.v), F(a[w].v)) ) {
 84                 a[w].v = child.v;
 85                 stk[top++] = w;
 86             }
 87             return ;
 88         }
 89     }
 90     a[++totnode] = child;
 91     next[totnode] = head[k];  head[k] = totnode;
 92     if ( F(child.v) == depth ) stk[top++] = totnode;
 93     else hp[hps++] = totnode;
 94 }
 95 
 96 void solve(void)
 97 {
 98     if (no_answer()) { puts("unsolvable"); return; }
 99     if (src == dest) { puts(""); return ; }
100     depth = -h[0][ZERO(src)];
101     totnode = 0;
102     hps = top = 0;
103     memset(head, 0, sizeof(head));
104     for (int i = 0; i != 9; ++i) {
105         depth += h[ DATA(src,i) ][i];
106     }
107     child.u = src;
108     child.v = MAKE(depth, 4, 1);
109     addnode();
110     unsigned int ID;
111     for ( ; LESS(depth, maxd); depth += 2) {
112         while (hps) {
113             ID = hp[--hps];
114             if ( F(a[ID].v) == depth ) {
115                 stk[top++] = ID;
116             }
117         }
118         while (top) {
119             ID = stk[--top];
120             state & cur = a[ID];
121             int i = ZERO(cur.u), j;
122             for (int r = 0; r != 4; ++r) {
123                 if (-1!=(j=mv[i][r]) && (D(cur.v)+r)!=3) {
124                     int t = DATA(cur.u, j);
125                     child.u = cur.u+SWP(i,j,t);
126                     int f = F(cur.v)+1+h[t][i]-h[t][j];
127                     child.v = MAKE(f,r,ID);
128                     if (child.u == dest) {
129                         a[++totnode] = child;
130                         print_sol(totnode); puts("");
131                         return ;
132                     }
133                     addnode();
134                 }
135             }
136         }
137     }
138 }
139 
140 int main()
141 {
142     init();
143     while (read_src()) solve();
144 
145     return 0;
146 }
View Code

 

BFS + 记忆化

 1 // zojfulltest: 1012ms
 2 # include <stdio.h>
 3 # include <ctype.h>
 4 # include <string.h>
 5 
 6 # define LESS(x,y) (((x)-(y))>>31)
 7 # define DATA(x,i) (((x)>>((i)*3))&0x7)
 8 # define ZERO(x) ((x)>>27)
 9 # define P(x) ((x)>>4)
10 # define D(x) ((x)&0xF)
11 # define MAKE(d,p) ((d)|((p)<<4))
12 # define SWP(i,j,t) (((t)<<(3*(i)))-((t)<<(3*(j)))+((j)<<27)-((i)<<27))
13 
14 const int totnode = 362881;
15 const int maxsize = 181445;
16 const int dest = 0x401F58D1;
17 const int destID = 40319;
18 const int fact[] = {1,1,2,6,24,120,720,5040,40320};
19 const int mv[][4] = {{-1,-1,1, 3},{-1,0,2, 4},{-1,1,-1, 5},
20     { 0,-1,4, 6},{ 1,3,5, 7},{ 2,4,-1, 8},
21     { 3,-1,7,-1},{ 4,6,8,-1},{ 5,7,-1,-1}};
22 const char mvs[] = "ulrd";
23 
24 struct state {
25     unsigned int s;
26     unsigned int c;
27 } hp[maxsize], child;
28 
29 unsigned int front, rear, src, table[totnode];
30 
31 unsigned int cantor(unsigned int s)
32 {
33     unsigned int ret = 0;
34     unsigned int t[9], i;
35     for (i = 0; i != 9; ++i) t[i] = DATA(s,i);
36     for (i = 0; DATA(s,i)||i==ZERO(s); ++i) ;
37     t[i] = 8;
38     for (i = 1; i != 9; ++i) {
39         unsigned int inv = 0;
40         for (int j = 0; j != i; ++j) {
41             inv += LESS(t[j],t[i]);
42         }
43         ret += inv*fact[i];
44     }
45     return ret;
46 }
47 void build_tree(void)
48 {
49     front = rear = 0;
50     child.s = dest, child.c = destID;
51     table[destID] = MAKE(4,destID);
52     hp[rear++] = child;
53     while (LESS(front, rear)) {
54         state & cur = hp[front++];
55         int i = ZERO(cur.s), d = table[cur.c], j;
56         for (int r = 0; r != 4; ++r) {
57             if (~(j=mv[i][r]) && (d+r)!=3) {
58                 child.s = cur.s+SWP(i,j,DATA(cur.s,j));
59                 child.c = cantor(child.s);
60                 if (table[child.c] == 0) {
61                     table[child.c] = MAKE(r, cur.c);
62                     hp[rear++] = child;
63                 }
64             }
65         }
66     }
67 }
68 bool read_src(void)
69 {
70     src = 0;
71     for (int ch, i = 0; i != 9; ) {
72         ch = getchar();
73         if (isdigit(ch)) src |= (((ch-'0')&0x7)<<(3*i++));
74         else if (ch == 'x') src |= ((i++)<<27);
75         else if (ch == EOF) return false;
76     }
77     return true;
78 }
79 void print_sol(int ID)
80 {
81     while (ID != destID) {
82         putchar(mvs[3-D(table[ID])]);
83         ID = P(table[ID]);
84     }
85 }
86 void solve(void)
87 {
88     unsigned int c = cantor(src);
89     if (!table[c]) printf("unsolvable");
90     else print_sol(c);
91     printf("\n");
92 }
93 int main()
94 {
95     build_tree();
96     while (read_src()) solve();
97 }
View Code

 

构造

 1 # include <stdio.h>
 2 # include <ctype.h>
 3 # include <string.h>
 4 
 5 # define LESS(x, y) (((x)-(y))>>31)
 6 # define REP(n) for ((i) = 0; src[i] != (n); ++(i))
 7 
 8 const char *t0[] = {"rd","d","ld","r","","l","ur","u","ul"};
 9 const char *t1[] = {"","lurd","urdllurd","uldr","","urdlurdllurd","ldruuldr","ldruldruuldr","rdluurdlurdllurd"};
10 const char *t2[] = {"","urddllur","urdlurddllur","","","rdllur","ldru","dlur","druldlur"};
11 const char *t3[] = {"","ruld","","","","urdl","dlurdrulurdlldru","drulurdl","rdluurdl"};
12 const char *t4   =  "ldrrulurdl";
13 const char *t5[] = {"","","","","","rdllur","ldru","dlur","druldlur"};
14 const char *t6[] = {"","","","","","rdlu","dlurdrulldrurdlu","","rdlurdlu"};
15 const char *t7   = "dlur";
16 const char *t8[] = {"","","","","","rd","","dr","rdlurd"};
17 const char *mvs  = "ulrd";
18 const int  mv[][4]  = {{-1,-1,1, 3},{-1,0,2, 4},{-1,1,-1, 5},
19     { 0,-1,4, 6},{ 1,3,5, 7},{ 2,4,-1, 8},
20     { 3,-1,7,-1},{ 4,6,8,-1},{ 5,7,-1,-1}
21 };
22 
23 unsigned int src[9], pos;
24 char ans[100], top;
25 
26 int mr(char ch)
27 {
28     switch(ch) {
29     case 'u':
30         return 0;
31     case 'l':
32         return 1;
33     case 'r':
34         return 2;
35     case 'd':
36         return 3;
37     }
38 }
39 void mov(const char * str)
40 {
41     int n = strlen(str);
42     for (int i = 0; i < n; ++i) {
43         int t = mv[pos][mr(str[i])];
44         src[pos] = src[t];
45         src[pos = t] = 0;
46     }
47     memcpy(ans+top, str, n);
48     top += n;
49 }
50 void solve(void)
51 {
52     int i;
53     top = 0;
54     mov( t0[pos] ); // 0->4
55     REP(1);
56     mov( t1[i] ); // 1->0
57     REP(3);
58     mov( t2[i] ); // 3->3
59     REP(2);
60     mov( t3[i] ); // 2->2
61     mov( t4 ); // 2->1, 3->2
62     REP(7);
63     mov( t5[i] ); // 7->3
64     REP(4);
65     mov( t6[i] ); // 4->7
66     mov( t7 ); // 4->3, 7->7
67     REP(5);
68     mov( t8[i] ); // 5->4, 0->8
69     ans[top] = 0;
70     if ( src[7] == 8 ) puts(ans);
71 }
72 bool no_answer(void)
73 {
74     int inv = -pos;
75     for (int i = 0; i != 8; ++i) {
76         for (int j = i+1; j != 9; ++j) {
77             inv += LESS(src[j], src[i]);
78         }
79     }
80     return ((inv)&0x1);
81 }
82 bool read_src(void)
83 {
84     for (int i = 0; i != 9; ) {
85         int ch = getchar();
86         if (isdigit(ch)) src[i++] = ch-'0';
87         else if (ch == 'x') src[pos = i++] = 0;
88         else if (ch == EOF) return false;
89     }
90     return true;
91 }
92 int main()
93 {
94     while ( read_src() ) {
95         if ( no_answer() ) puts("unsolvable");
96         else solve();
97     }
98     return 0;
99 }
View Code

 

fulltest.txt

posted on 2013-09-04 21:12  getgoing  阅读(922)  评论(0编辑  收藏  举报

导航