UVA1343 The Rotation Game

版权声明:听说这里让写版权声明~~~ https://blog.csdn.net/m0_37691414/article/details/83827437

题目大意

如图所示形状的棋盘上分别有8个1、2、3,要往A~H方向旋转棋盘,使中间8个方格数字相同。图(a)进行A操作后变为图(b),再进行C操作后变为图(c),这正是一个目标状态(因为中间8个方格数字相同)。要求旋转次数最少。如果有多解,操作序列的字典序应尽量小。

题目解析

本题是一个典型的状态空间搜索问题。本题采用IDEA*算法,详见代码。

#include<cstdio>
#include<algorithm>
using namespace std;
/*
	  	  A 0    B 1  
	      00    01
	      02    03
H 7	04 05 06 07 08 09 10 C 2
	      11    12
G 6	13 14 15 16 17 18 19 D 3
	      20    21
	      22    23
 		  F 5	E 4
 */
int line[8][7] = {
	{0, 2, 6, 11, 15, 20, 22}, 	//A
	{1, 3, 8, 12, 17, 21, 23}, 	// B
	{10, 9, 8, 7, 6, 5, 4},    	//C
	{19, 18, 17, 16, 15, 14, 13}//D
};
int rev[] = {5, 4, 7, 6, 1, 0, 3, 2};
const int center[] = {6, 7, 8, 12, 17, 16, 15, 11};
int a[25];
char ans[1100];
bool isFinal(){
	for(int i = 1; i < 8; ++i)
		if(a[center[i]] != a[center[0]]) return false;
	return true;
}
inline void move(int i){
	int temp = a[line[i][0]];
	for(int j = 0; j < 6; ++j)
		a[line[i][j]] = a[line[i]][j + 1];
	a[line[i][6]] = temp;
}
int diff(int target){
	int cnt = 0;
	for(int i = 0; i < 8; ++i)
		if(a[center[i]] != target) ++cnt;
	return cnt;
}
inline int h(){
	return min(min(diff(1), diff(2)), diff(3));
}
bool dfs(int d, int maxd){
	if(isFinal()){
		ans[d] = '\0';
		printf("%s\n", ans);
		return true;
	}
	if(h() + d > maxd) return false;
	for(int i = 0; i < 8; ++i){
		ans[d] = 'A' + i;
		move(i);
		if(dfs(d + 1, maxd)) return true;
		move(rev[i]);
	}
	return false;
}
int main(){
	for(int i = 4; i < 8; ++i)
		for(int j = 0; j < 7; ++j) line[i][j] = line[rev[i]][6 - j];
	while(scanf("%d", &a[0]) == 1 && a[0]){
		for(int i = 1; i < 24; ++i) scanf("%d", &a[i]);
		for(int i = 0; i < 24; ++i) if(!a[i]) return 0;
		if(isFinal()){
			printf("No moves needed\n");
		}else{
			for(int maxd = 1; ; maxd++)
				if(dfs(0, maxd)) break;
		}
		printf("%d\n", a[6]);
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/m0_37691414/article/details/83827437
今日推荐