您的位置:首页 > 其它

uva:10085 - The most distant state

2014-03-07 15:52 363 查看
10085 - The most distant state

题目大意:就和八码数问题类似,只是题目没有给最终的状态,要求你自己写出最终的状态,并且给出最短的路径。

解题思路:和八码数的解题思路是相同的,只是不给最终的状态,而是让它自己去bfs()直到最后已经不能在走的地步(再走下去就会重复的情况),这里的判重用了哈希判重。

然后就是存储路径问题:开了一个数组dis【】用来存放走到这个状态是哪个方向来的。然后在开一个fa【】数组:表示i的祖先是fa【i】。最终的状态是保存在st[rear - 1],那么它的前一个就是fa【rear- 1】,这样就可以反向的找出这条路径,存放到out数组中,最后就可以输出路径。

#include<stdio.h>
#include<string.h>

const int N = 3;
const int M = 1000000;
int n, head[M], next[M], dis[M], fa[M];
struct state{

int s

;
}st[M];

const char dx[] = {-1, 0, 1, 0};
const char dy[] = {0, -1, 0, 1};
const char f[] = "ULDR";

int hash(state &s1){

int v = 0;
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++){

v = v * 10 + s1.s[i][j];
}
return v % M;
}

int try_to_insert(int s){

int h = hash(st[s]);
int u = head[h];
while(u){

if(memcmp(st[u].s, st[s].s, sizeof(st[s]).s) == 0)
return 0;
u = next[u];
}
next[s] = head[h];
head[h] = s;
return 1;
}

int bfs(){

memset(head, 0, sizeof(head));
memset(fa, 0, sizeof(fa));
int front = 1, rear = 2;
while(front < rear){

state &s1 = st[front];
int x, y, i, j;

for(i = 0; i < N; i++)
for(j = 0; j < N; j++)
if(s1.s[i][j] == 0){
x = i; y = j;
break;
}

for(i = 0; i < 4; i++){

int nx = x + dx[i];
int ny = y + dy[i];
if(nx >= 0 && nx < N && ny >= 0 && ny < N){

state &t = st[rear];
memcpy(&t.s, &s1.s, sizeof(s1.s));
int tmp;
tmp = t.s[nx][ny];
t.s[nx][ny] = t.s[x][y];
t.s[x][y] = tmp;
dis[rear] = i;
fa[rear] = front;
if(try_to_insert(rear))
rear++;
}
}
front++;
}
return rear;
}

int main() {

scanf("%d", &n);
for(int v = 0; v < n; v++){

int i, j;
for(i = 0; i < N; i++)
for(j = 0; j < N; j++)
scanf("%d", &st[1].s[i][j]);

printf("Puzzle #%d\n", v + 1);
int rear = bfs();
for(i = 0; i < N; i++)
for(j = 0; j < N; j++){
if(j != N - 1)
printf("%d ", st[rear - 1].s[i][j]);
else
printf("%d\n", st[rear - 1].s[i][j]);
}

int k = rear - 1, out[10000];
for(i = 0; ; i++){

if(fa[k]){

out[i] = dis[k];
k = fa[k];

}
else
break;
}

for(j = i - 1; j >= 0; j--)
printf("%c", f[out[j]]);
printf("\n\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: