uva:10085 - The most distant state

来源:互联网 发布:马耳他十字机芯的优化 编辑:程序博客网 时间:2024/06/05 15:41

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[N][N];}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]);elseprintf("%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;}

 

0 0
原创粉丝点击