poj_2286 IDA*

题目大意

    给定一个由数字组成的#字型网格,和一定的移动规则,问最少需要多少次移动才能达到要求的结果。

题目分析

    要求最少需要几步到达结果,可以考虑广度优先搜索算法,或者迭代加深深度优先搜索(IDA*),这里使用IDA*算法。 
    在剪枝的时候: 
1. 考虑估价函数H(),表示当前中间八个格子中最少需要移动多少次才能相同(即8 - 
相同数字最多的个数); 
2. 前后两次移动不同为逆操作(即同一列,但不同方向) 
3. 不能连续7次进行移动同一列,且同一方向 
详细见 CanCut 函数。

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX(a, b) a>b? a :b
#define MAX_STEP 1000
int gOrderMoved[MAX_STEP];
int gIrreleventQueuee[4] = { 1, 0, 3, 2 };

int gCell[25];
int gCellIndexInQueue[4][7];
int gMoveOrder[4][2] = { { 0, 5 }, { 1, 4 }, { 7, 2 }, { 6, 3 } };
int gMoveQueue[8] = {0, 1, 2, 3, 1, 0, 3, 2};
int gMoveDir[8] = {0, 0, 1, 1, 1, 1, 0, 0};
int gCenterCellIndex[8] = { 6, 7, 8, 11, 12, 15, 16, 17 };
int gMinStep;
void Init(){
	gCellIndexInQueue[0][0] = 0;
	gCellIndexInQueue[0][1] = 2;
	gCellIndexInQueue[0][2] = 6;
	gCellIndexInQueue[0][3] = 11;
	gCellIndexInQueue[0][4] = 15;
	gCellIndexInQueue[0][5] = 20;
	gCellIndexInQueue[0][6] = 22;
	
	gCellIndexInQueue[1][0] = 1;
	gCellIndexInQueue[1][1] = 3;
	gCellIndexInQueue[1][2] = 8;
	gCellIndexInQueue[1][3] = 12;
	gCellIndexInQueue[1][4] = 17;
	gCellIndexInQueue[1][5] = 21;
	gCellIndexInQueue[1][6] = 23;

	for (int i = 0; i < 7; i++){
		gCellIndexInQueue[2][i] = 4 + i;
	}

	for (int i = 0; i < 7; i++){
		gCellIndexInQueue[3][i] = 13 + i;
	}
}

bool IsCenterSame(){
	int num = gCell[6];
	for (int i = 0; i < 8; i++){
		if (gCell[gCenterCellIndex[i]] != num){
			return false;
		}
	}
	return true;
}

void Rotate(int order){
	int move_queue = gMoveQueue[order];
	int move_dir = gMoveDir[order];
	int tmp;
	if (move_dir == 0){
		tmp = gCell[gCellIndexInQueue[move_queue][0]];
		for (int i = 0; i < 6; i++)
			gCell[gCellIndexInQueue[move_queue][i]] = gCell[gCellIndexInQueue[move_queue][i + 1]];
		gCell[gCellIndexInQueue[move_queue][6]] = tmp;
	}
	else{
		tmp = gCell[gCellIndexInQueue[move_queue][6]];
		for (int i = 6; i > 0; i--)
			gCell[gCellIndexInQueue[move_queue][i]] = gCell[gCellIndexInQueue[move_queue][i - 1]];
		gCell[gCellIndexInQueue[move_queue][0]] = tmp;
	}
}

int GetH(){
	int count[4] = { 0, 0, 0, 0 };
	for (int i = 0; i < 8; i++){
		count[gCell[gCenterCellIndex[i]]] ++;
	}
	int max = MAX(count[1], count[2]);
	max = MAX(max, count[3]);
	return 8 - max;
}

bool CanCut(int moved_step, int next_order){
	if (moved_step == 0){
		return false;
	}
	int k = moved_step - 1;
	int next_queue = gMoveQueue[next_order];
	int next_dir = gMoveDir[next_order];

	int irrelevent_queue = gIrreleventQueuee[next_queue];
	int same_order_count = 0;
	while (k >= 0){
		
		if (same_order_count >= 6)
			return true;

		while (k >= 0 && gMoveQueue[gOrderMoved[k]] == irrelevent_queue){
			k--;
		}
		if (k < 0){
			return false;
		}
		int queue = gMoveQueue[gOrderMoved[k]];
		int dir = gMoveDir[gOrderMoved[k]];
		if (queue == next_queue){
			if (dir != next_dir){
				return true;
			}
			else{
				same_order_count++;
			}
		}
		else{
			return false;
		}

		k--;
	}

	return false;
}
void MoveToCenterSame(int moved_step,  bool *moved_same){
	if (*moved_same){
		return;
	}
	if (IsCenterSame()){
		for (int i = 0; i < gMinStep; i++){
			printf("%c", 'A' + gOrderMoved[i]);
		}
		if (gMinStep == 0){
			printf("No moves needed");
		}
		printf("
");
		printf("%d
", gCell[6]);
		*moved_same = true;
		return;
	}
	if (moved_step + GetH() > gMinStep){
		return;
	}
	for (int next_order = 0; next_order < 8; next_order++){
		if (CanCut(moved_step, next_order)){
			continue;
		}
		if (*moved_same){
			return;
		}
		gOrderMoved[moved_step] = next_order;
		Rotate(next_order);
		MoveToCenterSame(moved_step + 1, moved_same);
		int reback_order = gMoveOrder[gMoveQueue[next_order]][! gMoveDir[next_order]];
		Rotate(reback_order);
	}
	
}

void Solve(){
	gMinStep = 0;
	while (true){
		bool moved_same = false;
		MoveToCenterSame(0, &moved_same);
		if (moved_same){
			break;
		}
		gMinStep++;
	}
}

int main(){
	Init();
	while (true){
		scanf("%d", gCell);
		if (gCell[0] == 0){
			break;
		}
		for (int i = 1; i < 24; i++){
			scanf("%d", gCell + i);
		}
		Solve();
		
	}
	return 0;
}
原文地址:https://www.cnblogs.com/gtarcoder/p/4780157.html