本文来自:http://kapinter.spaces.live.com/blog/cns!142AD4209363D971!665.entry
//盲目式搜索法--双向搜索法
//实质也是宽度优先搜索法
//但时空都是减少了一个数量级~~
#include <stdio.h>
#include <string.h>
typedef struct node {
long map; //存储一个棋盘状态
long father; //倒着找可以得到答案
char c; //记录算符
} node;
node queue[2][362880 + 1];
long tail[2], head[2];
long ans[2]; //存放结合节点
//-1表示还没出现
//否则为状态在队列中的位置
long hash[2][362880 + 1];
int main()
{
long ReadIn();
int NoAnswer(long);
void Solve();
void OutPut();
long map = ReadIn();
if (NoAnswer(map)) {
puts("unsolvable");
return 0;
}
queue[0][0].map = map;
queue[1][0].map = 123456780;
queue[0][0].father = -1;
queue[1][0].father = -1;
tail[0] = tail[1] = 0;
head[0] = head[1] = 0;
for (long i=0; i<362880+1; i++) {
hash[0][i] = hash[1][i] = -1;
}
Solve();
OutPut();
//printf("head[0]==%d head[1]==%d/n", head[0], head[1]);
return 0;
}
long ReadIn()
{
long i, t = 0;
char s[20];
for (i=0; i<9; i++) {
scanf("%s", s);
if (s[0]=='0' || s[0]=='x') {
t = t * 10;
}
else {
t = t * 10 + s[0] - '0';
}
}
return t;
}
int NoAnswer(long n)
{
long i, j, map[9];
long DeCompress(long *, long);
DeCompress(map, n);
long t = 0;
for (i=0; i<9; i++) {
if (map[i] == 0) continue;
for (j=i+1; j<9; j++) {
if (map[j] == 0) continue;
if (map[i] > map[j]) { t++; }
}
}
return (t % 2);
}
void Solve()
{
long map[9];
long DeCompress(long *, long);
void Expand(long, node);
long Hash(long *);
DeCompress(map, queue[0][0].map);
hash[0][Hash(map)] = 0;
DeCompress(map, queue[1][0].map);
hash[1][Hash(map)] = 0;
/* 一定是有解的,所以才这样写 */
node e;
long i = 0, j;
while (1) {
i = 1 - i;
j = 1 - i;
e = queue[i][tail[i]++];
DeCompress(map, e.map);
if ((ans[j] = hash[j][Hash(map)]) != -1) {
ans[i] = tail[i] - 1;
return;
}
Expand(i, e);
}
}
long DeCompress(long *map, long n)
{
long space;
for (int i=8; i>=0; i--) {
map[i] = n % 10;
n /= 10;
if (map[i] == 0) { space = i; }
}
return space;
}
void Expand(long sign, node e)
{
//long DeCompress(long *, long);
void swap(long &, long &);
long Hash(long *);
long Compress(long *);
long map[9], temp;
long space = DeCompress(map, e.map);
if (space >= 3) { //can up
swap(map[space - 3], map[space]);
if (hash[sign][temp = Hash(map)] == -1) {
queue[sign][++head[sign]].map = Compress(map);
queue[sign][head[sign]].father = tail[sign] - 1;
queue[sign][head[sign]].c = 'u';
hash[sign][temp] = head[sign];
}
swap(map[space - 3], map[space]);
}
if (space <= 5) { //can down
swap(map[space + 3], map[space]);
if (hash[sign][temp = Hash(map)] == -1) {
queue[sign][++head[sign]].map = Compress(map);
queue[sign][head[sign]].father = tail[sign] - 1;
queue[sign][head[sign]].c = 'd';
hash[sign][temp] = head[sign];
}
swap(map[space + 3], map[space]);
}
if (space % 3 != 0) { //can left
swap(map[space - 1], map[space]);
if (hash[sign][temp = Hash(map)] == -1) {
queue[sign][++head[sign]].map = Compress(map);
queue[sign][head[sign]].father = tail[sign] - 1;
queue[sign][head[sign]].c = 'l';
hash[sign][temp] = head[sign];
}
swap(map[space - 1], map[space]);
}
if (space % 3 != 2) { //can right
swap(map[space + 1], map[space]);
if (hash[sign][temp = Hash(map)] == -1) {
queue[sign][++head[sign]].map = Compress(map);
queue[sign][head[sign]].father = tail[sign] - 1;
queue[sign][head[sign]].c = 'r';
hash[sign][temp] = head[sign];
}
swap(map[space + 1], map[space]);
}
}
void swap(long &x, long &y)
{
x ^= y;
y ^= x;
x ^= y;
}
long Compress(long *map)
{
long t = 0, i;
for (i=0; i<9; i++) {
t = t * 10 + map[i];
}
return t;
}
long Hash(long *map)
{
static long formula[9] =
{ 1, 1, 2, 6, 24, 120, 720, 5040, 40320 };
long temp[9];
for (long i=0; i<9; i++) {
temp[i] = map[i];
}
long t = 0;
for (i=0; i<9; i++) {
t += temp[i] * formula[8 - i];
for (long j=i+1; j<9; j++) {
if (temp[j] > temp[i]) temp[j]--;
}
}
return t;
}
void OutPut()
{
char s[200];
long tail, head;
char opposite[256];
opposite['u'] = 'd';
opposite['d'] = 'u';
opposite['l'] = 'r';
opposite['r'] = 'l';
head = 100;
tail = 100;
while (queue[0][ans[0]].father != -1) {
s[--head] = queue[0][ans[0]].c;
ans[0] = queue[0][ans[0]].father;
}
while (queue[1][ans[1]].father != -1) {
s[tail++] = opposite[queue[1][ans[1]].c];
ans[1] = queue[1][ans[1]].father;
}
s[tail] = 0;
puts(&s[head]);
} |
---|
2 3 4 1 5 x 7 6 8
ullddrurdllurrdlurd
Press any key to continue
|
---|