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

你可能感兴趣的:(poj)