清华数据结构玩具AC85

本人采用的是蛮力算法,即,对于每种状态,将可能接下去的路都进行一遍(共3条路可以走)

然后,终止条件是,最终可用于前进的步子为0,即,count=hi。这时候,则说明每一个步子都是重复前人的步子,最终必然又会回到最初的起点,故终止。或者终止条件是,找到答案了。

但是蛮力算法耗时久,无论如何也无法在1s内完成计算。

而根据前人的成功例子来看,必然存在某种规则,我也想了蛮久的。可暂时还是没发现规则,由于我的目的是学习数据结构,所以对魔方复原的规则在此也就不再深究了,也就只能拿85了。。。(不甘心呀QAQ)

#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#define maxn 130309//maxn取得足够大,保证没有冲突
#define max_num 1000
using namespace std;
struct toyy {
	int toy[8];
	int effect = 1;//用来记录当前的toy是否有效,无效则遍历时跳过
	int h = 0;//用来记录当前步数
	toyy&operator=(const toyy&a)
	{
		for (auto i = 0; i < 8; i++)toy[i] = a.toy[i];
		effect = a.effect;
		h = a.h;
		return *this;
	}
};
int toys[8] = { 1,2,3,4,5,6,7,8 };
struct boxx {
	int num = 0;
	int index = 0;
	boxx&operator=(const boxx box)
	{
		num = box.num;
		//index = box.index;
		return*this;
	}
};
boxx box[maxn];
boxx box1[maxn];
toyy toy[maxn];
int shuru[max_num][8];
int caculate(int a[], int n)
{
	int num = 0;
	for (auto i = 0; i<n; i++)
	{
		num *= 10;
		num += a[i];
	}
	return num;
}
int hash_code(int a[], int n)
{
	return caculate(a, n) % maxn;
}
void create_list()
{
	int count = 0;
	int list[8];
	for (auto a = 1; a < 9; a++)
	{
		list[0] = a;
		for (auto b = 1; b < 9; b++)
			if (b != a) {
				list[1] = b;
				for (auto c = 1; c < 9; c++)
					if (c != a && c != b) {
						list[2] = c;
						for (auto d = 1; d < 9; d++)
							if (d != a && d != b && d != c) {
								list[3] = d;
								for (auto e = 1; e < 9; e++)
									if (e != a && e != b && e != c && e != d) {
										list[4] = e;
										for (auto f = 1; f < 9; f++)
											if (f != a && f != b && f != c && f != d && f != e) {
												list[5] = f;
												for (auto g = 1; g < 9; g++)
													if (g != a && g != b && g != c && g != d && g != e && g != f) {
														list[6] = g;
														for (auto h = 1; h < 9; h++)
															if (h != a && h != b && h != c && h != d && h != e && h != f && h != g)
															{
																list[7] = h;
																auto temp = hash_code(list, 8);
																for (auto j = 1; j < maxn; j++)
																{
																	if (box[temp].num == 0) {
																		box[temp].num = 1;
																		box[temp].index = caculate(list, 8); break;
																	}
																	else {
																		temp = (temp + j * j) % maxn;
																	}
																}
																//for (auto i = 0; i < 8; i++)printf("%d ", list[i]);
																//printf("\n");
																//printf("box_hash= %d,hash_code= %d\n", box[hash_code(list, 8)], hash_code(list, 8));
															}
													}
											}
									}
							}
					}
			}
	}
}
//交换
void swap(int i, int j, int toy[])
{
	auto t = toy[i];
	toy[i] = toy[j];
	toy[j] = t;
}
//上下交换
void change_top_bottom(int toy[])
{
	for (auto i = 0; i < 4; i++)swap(i, 7 - i, toy);
}
//循环右移
void change_right(int toy[])
{
	auto t = toy[3];
	toy[3] = toy[2]; toy[2] = toy[1]; toy[1] = toy[0]; toy[0] = t;
	auto h = toy[4];
	toy[4] = toy[5]; toy[5] = toy[6]; toy[6] = toy[7]; toy[7] = h;
}
//中心顺时针旋转
void change_mid_rotate(int toy[])
{
	auto t = toy[2];
	toy[2] = toy[1];
	toy[1] = toy[6];
	toy[6] = toy[5];
	toy[5] = t;
}
int result = caculate(toys, 8);
//用于检查翻转后的数值是否重复了,如果重复,effect=0,下次遍历到就会自动跳过。否则,则让box=0,为下次重复做准备
//同时还检查了是否此toy的数值为目标值,如果是,则返回真,反之,返回假
bool box_check(toyy toy[], int hi)
{
	auto t1 = caculate(toy[hi].toy, 8);
	auto t = t1 % maxn;
	for (auto j = 1; j<maxn; j++)
		if ((box[t].index != t1)) {
			t = (t + j * j) % maxn;
		}
		else break;
		if (box[t].num == 1) {
			box[t].num = 0;
		}
		else {
			toy[hi].effect = 0;
		}
		if (t1 == result)return true;
		else return false;
}
int main()
{
#ifndef _OJ_
	freopen("toy.txt", "r", stdin);
	// freopen("travelout.txt", "w", stdout);
#endif
	create_list();
	for (auto i = 0; i < maxn; i++)box1[i] = box[i];
	int n;
	scanf("%d", &n);
	auto t = 0;
	while (t < n)
	{
		for (auto i = 0; i < 8; i++) scanf("%d", &shuru[t][i]);
		t++;
	}
	int number[max_num];//number是用来记录旋转次数
	for (auto i = 0; i < t; i++)
	{
		int count = 0, hi = 1, anwser = 0;
		for (auto j = 0; j < 8; j++)toy[0].toy[j] = shuru[i][j];
		if (caculate(toy[count].toy, 8) == result) { number[i] = 0; anwser = 1; }
		else
			while (count < hi)
			{
				toy[hi] = toy[count];
				toy[hi].h++;
				change_top_bottom(toy[hi].toy);
				if (box_check(toy, hi)) { number[i] = toy[hi].h; anwser = 1; break; }
				if (toy[hi].effect == 1)hi++;
				toy[hi] = toy[count]; toy[hi].h++;
				change_right(toy[hi].toy);
				if (box_check(toy, hi)) { number[i] = toy[hi].h; anwser = 1; break; }
				if (toy[hi].effect == 1)hi++;
				toy[hi] = toy[count]; toy[hi].h++;
				change_mid_rotate(toy[hi].toy);
				if (box_check(toy, hi)) { number[i] = toy[hi].h; anwser = 1; break; }
				if (toy[hi].effect == 1)hi++;
				count++;
				//if (toy[hi].h > 70)break;
			}
		if (anwser == 0)number[i] = -1;
		for (auto i = 0; i < maxn; i++)box[i] = box1[i];
	}
	for (auto i = 0; i<t; i++)
		printf("%d\n", number[i]);
	//printf("h= %d\n",)
}

猜你喜欢

转载自blog.csdn.net/hgtjcxy/article/details/81267994