本题的判重的状态的保存用到了全排列的变进制hash方法.
详细的解释见:
http://www.cppblog.com/longzxr/archive/2009/08/04/92151.html
下面是我三个版本的算法实现
分别为:
单向BFS
A* BFS
双向BFS
对于本题, 效率递增.
一. 下面是单向BFS算法的实现
目前我的效率只有907MS, 险超时.
Memory: 4132K, Time: 907MS
二. 加上A*算法估价后的A*搜索代码
Memory: 3868K, Time: 391MS
三. 这是使用双向BFS的代码, 事实证明, 这题还是使用双向BFS更快.
Rank: 207 Memeory: 3232K, Time: 0MS
附:
IDA*算法:
#include <stdio.h>
#include <string.h>
#define ABS(x) ((x)<0?-(x):(x))
typedef struct
{
int stat[10];
int x;
}node_t;
node_t st;
int stack[1000002];
int dist[10][10];
/*
* d -- 0
* r --- 1
* u --- 2
* l --- 3
*/
char act[] = "drul";
int dir[4] = {3, 1, -3, -1};
int mv[10][5] = {{0},
{2, 0, 1}, /* 1 */
{3, 0, 1, 3}, /* 2 */
{2, 0, 3}, /* 3 */
{3, 0, 1, 2}, /* 4 */
{4, 0, 1, 2, 3},/* 5 */
{3, 0, 2, 3}, /* 6 */
{2, 1, 2}, /* 7 */
{3, 1, 2, 3}, /* 8 */
{2, 2, 3} /* 9 */
};
int found, top, min;
int get_dist(int i, int j)
{
int x1 = (i - 1) / 3 + 1;
int y1 = (i - 1) % 3 + 1;
int x2 = (j - 1) / 3 + 1;
int y2 = (j - 1) % 3 + 1;
return ABS(x1 - x2) + ABS(y1 - y2);
}
void init_dist()
{
int i, j;
for(i = 1;i <= 9; i++)
for(j = 1;j <= 9; j++) dist[i][j] = get_dist(i, j);
}
int heur(node_t node)
{
int sum = 0, i;
for(i = 1;i <= 9; i++) sum += dist[i][node.stat[i]];
return sum;
}
int is_solvable(node_t st)
{
int res = 0, i, j;
for(i = 1;i <= 9; i++)
for(j = 1;j < i; j++) if(st.stat[i] < st.stat[j]) res++;
res += dist[9][st.x];
return (res & 1) == 0;
}
int init()
{
char str[2];
int i;
for(i = 1;i <= 9; i++)
{
if(scanf("%s", str) == EOF) return 0;
if(str[0] == 'x')
{
st.stat[i] = 9;
st.x = i;
}
else st.stat[i] = str[0] - '0';
}
return 1;
}
void output()
{
int i;
for(i = 1;i <= top; i++) printf("%c", act[stack[i]]);
printf("\n");
}
void dfs(int p, int dp, int maxdp)
{
int f = heur(st);
int i, k, t;
if(min > f) min = f;
if(f + dp > maxdp || found) return;
if(f == 0)
{
output();
found = 1;
return;
}
for(i = 1;i <= mv[p][0]; i++)
{
k = mv[p][i];
t = dir[k] + p;
st.stat[p] = st.stat[t];
st.stat[t] = 9;
stack[++top] = k;
dfs(t, dp + 1, maxdp);
top--;
st.stat[t] = st.stat[p];
st.stat[p] = 9;
}
}
void ida_star(node_t st)
{
int maxdp = heur(st);
found = 0;
while(found == 0)
{
min = 0x7fffffff;
top = 0;
dfs(st.x, 0, maxdp);
maxdp += min;
}
}
int main()
{
init_dist();
while(init())
{
if(is_solvable(st) == 0)
{
printf("unsolvable\n");
continue;
}
ida_star(st);
}
return 0;
}