本人采用的是蛮力算法,即,对于每种状态,将可能接下去的路都进行一遍(共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",)
}