ZOJ 1217 eight

八数码,双广、A*都超时了(可能是写得不好),IDA*通过了;

在POJ上是16MS(和双广一样,A* 60MS左右),HDOJ上是800MS左右(双广是500MS),ZOJ上只有IDA*没超时(2480MS)。

  1 # include <stdio.h>

  2 # include <math.h>

  3 # include <string.h>

  4 

  5 # define MIN(x, y) ((x)<(y) ? (x):(y))

  6 

  7 # define N 9

  8 # define DIR_N 4

  9 # define INF 0x7fffffff

 10 # define MAX_DEPTH 1000

 11 # define SIZE 3

 12 

 13 char solved;

 14 char start[N], goal[N];

 15 char cur[N];

 16 

 17 int bound;

 18 const char md[] = {'u', 'l', 'r', 'd'};

 19 const short int dir[][2] = {{-1,0}, {0,-1}, {0,1}, {1,0}};

 20 char path[MAX_DEPTH];

 21 

 22 void solve(void);

 23 char read(char *s);

 24 int IDAstar(void);

 25 char bool_inv(char *s);

 26 int heu(void);

 27 int dfs(int zero_pos, int depth, char direction);

 28 

 29 int main()

 30 {

 31     int i;

 32     

 33     for (i = 0; i < N-1; ++i)

 34         goal[i] = i + 1;

 35     goal[N-1] = 0;

 36     while (read(start))

 37     {

 38         memcpy(cur, start, N);

 39         solve();

 40     }

 41     

 42     return 0;

 43 }

 44 

 45 void solve()

 46 {

 47     int i, depth;

 48 

 49     if (bool_inv(start) != bool_inv(goal)) puts("unsolvable");

 50     else

 51     {

 52         memset(path, -1, sizeof(path));

 53         depth = IDAstar();

 54         for (i = 0; path[i]!=-1; ++i)

 55         {

 56             putchar(md[path[i]]);

 57         }

 58         putchar('\n');

 59     }

 60 }

 61 

 62 char read(char *s)

 63 {

 64     char c[5];

 65     int i;

 66 

 67     if (EOF == scanf("%s", c)) return 0;

 68     else s[0] = (c[0]=='x' ? 0:c[0]-'0');

 69     for (i = 1; i < N; ++i)

 70     {

 71         scanf("%s", c);

 72         s[i] = (c[0]=='x' ? 0:c[0]-'0');

 73     }

 74     

 75     return 1;

 76 }

 77 

 78 int IDAstar(void)

 79 {

 80     int i;

 81 

 82     solved = 0;

 83     bound = heu();

 84 

 85     for (i = 0; start[i] && i < N; ++i) ;

 86 

 87     while (!solved && bound<100)

 88     {

 89         bound = dfs(i, 0, -10);

 90     }

 91 

 92     return bound;

 93 }

 94 

 95 int dfs(int pos, int depth, char d)

 96 {

 97     int h, i, nx, ny, npos, nbound, t;

 98 

 99     h = heu();

100 

101     if (depth+h > bound) return depth+h;

102     if (h == 0)

103     {

104        /* printf("depth = %d.\n", depth); */

105         solved = 1;

106         return depth;

107     }

108 

109     nbound = INF;

110     for (i = 0; i < DIR_N; ++i)

111     {

112         if (i+d == DIR_N-1) continue;

113         nx = pos/SIZE + dir[i][0];

114         ny = pos%SIZE + dir[i][1];

115         if (0<=nx && nx<SIZE && 0<=ny && ny<SIZE)

116         {

117             path[depth] = i;

118             npos = nx*SIZE + ny;

119             cur[pos] = cur[npos]; cur[npos] = 0;     /* pos -> npos */

120             t = dfs(npos, depth+1, i);

121             if (solved) return t;

122             nbound = MIN(nbound, t);

123             cur[npos] = cur[pos]; cur[pos] = 0;

124         }

125     }

126     return nbound;

127 }

128 

129 int heu(void)            /* return heu(cur_state) */

130 {

131     char ch;

132     int i, j, ret;

133 

134     ret = 0;

135     for (i = 0; i < N; ++i)

136     {

137         ch = goal[i];

138         if (ch == 0) continue;

139         for (j = 0; j < N; ++j)

140         {

141             if (ch == cur[j])

142             {

143                 ret = ret + abs(i/SIZE-j/SIZE) + abs(i%SIZE-j%SIZE);

144             }

145         }

146     }

147 

148     return ret;

149 }

150 

151 char bool_inv(char *s)

152 {

153     char ch, ret;

154     int i, j;

155 

156     ret = 0;

157     for (i = 0; i < N-1; ++i)

158     {

159         if ((ch = s[i]) == 0) continue;

160         for (j = i+1; j < N; ++j)

161         {

162             if (s[j] && s[j]<ch) ret = 1 - ret;

163         }

164     }

165 

166     return ret;

167 }

你可能感兴趣的:(ZOJ)