魔板

题目描述

思路

代码

#include <cstdio>
#include <cstring>
#include <queue>

int tar[10], tmp[10], rec[10];
bool vis[40500];
int fa[40500], ed, ans, ant;
char act[40500];
int jc[10] = {1, 1, 2, 6, 24, 120, 720, 5040};
std::queue<int> q, p;

int get(int * arr) {
	memset(rec, 0, sizeof(rec));
	int res = 0;
	for (int i = 1; i <= 8; ++i) {
		int k = 0;
		for (int j = arr[i]; j >= 1; --j) {
			if (!rec[j]) k++; 
		}
		rec[arr[i]] = 1;
		res += (k - 1) * jc[8 - i];
	}
	return res;
}
void trans(int x, int * arr) {
	memset(rec, 0, sizeof(rec));
	for (int i = 1, j, k; i <= 8; ++i) {
		j = x / jc[8 - i] + 1;
		x = x % jc[8 - i];
		for (k = 1; k <= 8; ++k) {
			if (!rec[k]) j--;
			if (j == 0) {
				arr[i] = k;
				rec[k] = 1;
				break;
			}
		}
	}
}
void swap(int &a, int &b) {
	int i = a; a = b; b = i;
}
void updateA(int * arr) {
	swap(arr[1], arr[8]);
	swap(arr[2], arr[7]);
	swap(arr[3], arr[6]);
	swap(arr[4], arr[5]);
}
void updateB(int * arr) {
	int j = arr[4], k = arr[5];
	for (int i = 4; i >= 2; --i) arr[i] = arr[i - 1];
	for (int i = 5; i <= 7; ++i) arr[i] = arr[i + 1];
	arr[1] = j, arr[8] = k;
}
void updateC(int * arr) {
	int i = arr[2];
	arr[2] = arr[7];
	arr[7] = arr[6];
	arr[6] = arr[3];
	arr[3] = i;
}
void write(int x) {
	if (fa[x] != x) {
		write(fa[x]);
		putchar(act[x]);
	}
}

int main() {
	for (int i = 1; i <= 8; ++i) scanf("%d", &tar[i]);
	ed = get(tar);
	for (int i = 1; i <= 8; ++i) tar[i] = i;
	int x = get(tar), a, b, y;
	q.push(x);
	p.push(0);
	vis[x] = true; 
	fa[x] = x;
	while (!q.empty()) {
		x = q.front(); 
		y = p.front();
		q.pop(); p.pop();
		trans(x, tar);
		if (x == ed) { ans = y; break; }
		memcpy(tmp, tar, sizeof(tar));
		updateA(tmp);
		a = get(tmp);
		if (!vis[a]) q.push(a), p.push(y + 1), fa[a] = x, act[a] = 'A', vis[a] = true;

		memcpy(tmp, tar, sizeof(tar));
		updateB(tmp); 
		a = get(tmp);
		if (!vis[a]) q.push(a), p.push(y + 1), fa[a] = x, act[a] = 'B', vis[a] = true;
	
		memcpy(tmp, tar, sizeof(tar));
		updateC(tmp); 
		a = get(tmp);
		if (!vis[a]) q.push(a), p.push(y + 1), fa[a] = x, act[a] = 'C', vis[a] = true;
	}
	
	printf("%d
", ans);
	write(ed);
	return 0;
}
原文地址:https://www.cnblogs.com/liuzz-20180701/p/11598150.html