uva:10085 - The most distant state

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]);
				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;
}

 

你可能感兴趣的:(uva:10085 - The most distant state)