问题描述

二阶魔方是 2x2x2 的立方体结构魔方,它共有 8 块,如下图所示:

图1  二阶魔方示意图

我们可以定义魔方作为一个正六面体的六个面为 F(ront), B(ack), U(p), D(own), L(eft), R(ight)。我们根据先前后后,先上后下,先左后右的方法,依次给魔方的每一个方块编号,块编号的方式如下表所示:

表1  二阶魔方块编号表

带块编号的魔方平面展开图如下图所示:

图2  带块编号的二阶魔方平面展开图

与三阶魔方不同,二阶魔方的每个块均有 3 个面露在外面,并被涂为不同的颜色,共 6 种颜色。我们定义整个魔方作为魔方共有 24 个面。任意两个面,如果颜色不同,那么显然是不同的两个面;若颜色相同,但与其在同一个块上的另外两种颜色不可能全相同,那么这两个面也是不同的两个面。因此,二阶魔方的 24 个面各不相同。所以我们可以给每个面一个编号( 0 到 23 ),面编号的方式如下表所示(其中“ 0F”表示“第 0 块;前面”):

表2  二阶魔方面编号表

带面编号的魔方平面展开图如下图所示:

图3  带面编号的二阶魔方平面展开图

根据这种面编号的方法,一个复原后的魔方可以写成一个长度为24的数组: [0, 1, 2, 3, …, 23] ,一个被打乱的魔方可以写成这个数组的重排,例如下面的这种情况:

图4  一个打乱的二阶魔方平面展开图

此时用数组表示这个状态为: [10, 11, 9, 5, 3, 4, 6, 7, 8, 22, 23, 21, 1, 2, 0, 14, 12, 13, 18, 19, 20, 17, 15, 16]。

我们定义魔方的状态是不受视角影响的,也就是说只有拧动魔方后,其状态才会改变。这里我们可以分析一下二阶魔方存在多少种不同的状态。由于视角的不同,二阶魔方的每一种状态会对应到 24 种不同的如图 2 所示的平面展开图(6 个面均可作为正面,同时又可以以正面为轴滚动 4 次,得到 6x4=24 种不同的平面展开图)。二阶魔方 8 个块的位置均可任意互换(8! 种情况)。如果固定一个块作为参考,那么另外 7个块中每个都可以有 3 种不同的朝向(37 种情况)。于是我们得到了 8!37 种不同的平面展开图。所以二阶魔方的状态总数为:

在还原二阶魔方的过程中,“FRU注释”是一种比较通用的还原步骤注释。FRU注释只旋转魔方的 正面(F: front右面(R: right和 上面(U: up,并且可以分别 顺时针旋转90°(用+表示)180°(用2表示)和 逆时针旋转90°(用-表示)。这样魔方每步就有 9 种的变化方式(注意到在可以调整视角的情况下其他的旋转方式是等价于这 9 种方式中的某一种的)。下图描述了FRU注释的操作过程:

图5  FRU注释的 9 种魔方旋转方式

若采用FRU注释的 9 种方式旋转魔方,对于二阶魔方的任意一种状态,最坏情况下只需要 11 步就可以将魔方还原。其中,在 3674160 种不同的魔方状态中,有一半左右(1887748 种)的状态最少需要 9 步才能还原魔方。下表给出了最少旋转次数和对应的状态总数的关系:

表3  还原魔方所需最少步数与状态个数的关系

我们的问题就是:给出一个被打乱的二阶魔方(根据前文的方法表示成打乱顺序的数组 [0, 1, 2, 3, …, 23] ),求出还原魔方的最少步数(每步只能是FRU注释的 9 种操作的一种),并且按照 FRU注释 给出每步的具体操作以及每步操作后的结果(长度为 24 的数组)。

输入格式

输入为某种被打乱的魔方的状态,输入的格式为打乱顺序的数组 [0, 1, 2, 3, …, 23] 。

注意到FRU注释的9种旋转方式均不会改变魔方中一块的状态(后下左),所以还原后的魔方的状态由这个块的初始状态唯一确定。本题中为了使得还原后的魔方状态用数组表示为 [0, 1, 2, 3, …, 23] ,会保证所有测试数据的数组的 18, 19, 20 均在原本的位置。

输出格式

首先第一行输出一个正整数 n ,表示还原魔方所需的 最少 步数。

接下来的输出有 2n 行(若 n = 0 则无需输出)。第 (2i – 1) 行输出一个字符串,表示还原魔方的每步操作,字符串要求是 9 种旋转操作(F+,F2,F-,R+,R2,R-,U+,U2,U-)中的一种。第 (2i) 行输出一个长度为 24 的数组,这个数组表示经过第 (2i – 1) 行的操作后魔方的状态。

注意:使用最少步数还原魔方可以有多种操作方式,请输出任意一种即可。前 4 组测试数据保证最少步数不超过 7 步,后 6 组的测试数据无限制。

输入样例

10 11 9 5 3 4 6 7 8 22 23 21 1 2 0 14 12 13 18 19 20 17 15 16

输出样例

2
U-
0 1 2 11 9 10 6 7 8 22 23 21 12 13 14 4 5 3 18 19 20 17 15 16
R-
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

提示

本题可能需要了解“状态空间搜索”、“状态压缩”和“双向广度优先搜索”。这部分内容可以参考百度百科的 搜索算法。

1 状态空间搜索

状态空间搜索就是将问题的求解过程转化为从初始状态到目标状态寻找路径的过程。状态空间可以看成一个图,图上的点就是某个 状态 ,边则是某个状态到另一个状态的 状态转移 关系。使用状态空间搜索求解问题的关键就是:利用有效的数据结构对状态进行存储,实现状态间的转移关系,进而使用 深度优先搜索 或 广度优先搜索 算法计算初始状态到目标状态路径。

本题中,状态就是魔方的状态,即长度为 24 的数组,状态转移关系则是FRU注释中的 9 种操作。

所以,我们需要把FRU注释中的 9 中操作对应的颜色变换列举出来(即变换后的面的编号对应原来的哪个编号),然后依据输入给的初始状态,通过广度优先搜索遍历可能转移到的状态,直到搜索到最终状态( [0, 1, 2, 3, …, 23] ),便求出了还原魔方的最少步数,并且可以通过回溯得到每步的操作。

2 状态压缩

在搜索的过程中,我们需要标记哪些状态已经被访问过了。对于简单的搜索,我们可以直接用 bool 数组来标记状态访问与否。但是,本题的状态是一个长度为 24 的数组,我们需要建立哈希表来存储。为了简化程序,这里建议大家直接使用 C++ STL 中的 map 或 unordered_map 来实现哈希表,并且状态的表示也用STL 中的 vector 而不是数组(因为 vector 可以直接用在 map 中,而数组不行)。不过,用数组或 vector 表示一个状态会占用较多的内存,并且会延长哈希表定位键值的时间。

状态压缩要考虑的问题是如何用 更有效的方式对状态进行编码。对本题而言,注意到只有 6 种颜色,所以可以先将颜色编号( 0 ~ 5 ),进而使用 六进制 对长度为 24 的状态数组编码:六进制的第 i 位,表示第 i个位置的颜色。所以我们需要一个取值范围在 0 ~ 624-1 的数字来表示一个状态,这个取值范围恰好在无符号 8 字节整数(C++中的 unsigned long long)的取值范围(0 ~ 264-1)内。于是,我们在使用 map 标记状态时,就不需要使用 vector 作为键值,而是使用这个 unsigned long long 的编码值了。比如最初状态的数组使用六进制状态压缩的表示为:

而我们要获取第 i 个位置的颜色时,便可直接让压缩后的编码对 6i+1 取模后,再对 6i 取整即可。

也可以根据块编号以及块状态进行编码,8 块的其中一块(块编号为6的块)的位置及状态已经是确定的了,因此最多只有 7 个块的顺序( 7! )及7个块的状态( 3^7 )。实际上确定了剩余 7 个块中 6 个块的状态,最后一个块的状态就已经确定了,因此总状态数为( 7!*3^6 = 3674160 ),与前面的分析相同。所以可以使用14位的 unsigned long long 进行编码,如还原后的状态为:01234570000000(前 7 位表示块的位置,后 7 位表示每个块的状态( 0, 1, 2 ))。

当然,以上两种压缩方法只是简单的例子,存在更好的压缩方式,因为总状态数仅有 3674160 种。

3 双向广度优先搜索

广度优先搜索的过程中需要维护一个存储待搜索状态的队列,因此广度优先搜索的问题就是会占用很大的内存。而对于目标状态确定的问题来说,双向广度优先搜索是减少内存开销的一个有效手段。双向广度优先搜索的思想就是 从 初始状态 和 目标状态 同时进行广度优先搜索,保持搜索的层数同步,最终两个方向的搜索所遍历的状态会在中间相遇,从而求出了最短的路径。这样一来便减去了很多不必要的搜索状态,因为搜索的过程中每层的状态数是近似成倍增加的。

使用双向广度优先搜索需要确定初始状态和目标状态。对于本题而言,初始状态是直接输入的,而目标状态即为 [0, 1, 2, 3, …, 23]。另外,对于本题而言,若前一步的操作为F(+, -, 2),则后一步的操作不会仍为F(+, -, 2),因为任意连续的两次以上F的操作可以用某种一次以下F的操作表示,U和R同理。依此编写代码也可以减少时间和空间的开销。

# define _CRT_SECURE_NO_WARNINGS
# define uint64 unsigned long long
# include <cstdio>
# include <queue>
# include <map>
using namespace std;typedef struct Station {uint64 code;int step;int operate;int dir;Station * father;Station() :step(0), operate(-1), dir(-1), father(NULL) {}
}*station;map <uint64, station> visited;
uint64 six_pow(int n) {uint64 ans = 1;for (int i = 0; i < n; ++i) {ans = ans * 6;}return ans;
}
uint64 encode(int * face) {int color[24];for (int i = 0; i < 24; ++i) {switch (face[i]) {case 0:  color[i] = 3; break;case 1:  color[i] = 0; break;case 2:  color[i] = 2; break;case 3:  color[i] = 3; break;case 4:  color[i] = 2; break;case 5:  color[i] = 4; break;case 6:  color[i] = 3; break;case 7:  color[i] = 5; break;case 8:  color[i] = 0; break;case 9:  color[i] = 3; break;case 10: color[i] = 4; break;case 11: color[i] = 5; break;case 12: color[i] = 1; break;case 13: color[i] = 2; break;case 14: color[i] = 0; break;case 15: color[i] = 1; break;case 16: color[i] = 4; break;case 17: color[i] = 2; break;case 18: color[i] = 1; break;case 19: color[i] = 0; break;case 20: color[i] = 5; break;case 21: color[i] = 1; break;case 22: color[i] = 5; break;case 23: color[i] = 4;}}uint64 code = 0;for (int i = 0; i < 24; ++i) {code = code + (color[i]) * six_pow(i);}return code;
}
void decode(const uint64 code, int * face) {uint64 temp;int color[24];for (int i = 0; i < 24; ++i) {temp = code % six_pow(i + 1);color[i] = temp / six_pow(i);}for (int j = 0; j < 8; ++j) {int sum = color[3 * j] + color[3 * j + 1] + color[3 * j + 2];switch (sum) {case 5: {for (int k = 0; k < 3; ++k) {if (color[3 * j + k] == 3)face[3 * j + k] = 0;else if (color[3 * j + k] == 0)face[3 * j + k] = 1;else face[3 * j + k] = 2;}}break;case 9: {for (int k = 0; k < 3; ++k) {if (color[3 * j + k] == 3)face[3 * j + k] = 3;else if (color[3 * j + k] == 2)face[3 * j + k] = 4;else face[3 * j + k] = 5;}}break;case 8: {for (int k = 0; k < 3; ++k) {if (color[3 * j + k] == 3)face[3 * j + k] = 6;else if (color[3 * j + k] == 5)face[3 * j + k] = 7;else face[3 * j + k] = 8;}}break;case 12: {for (int k = 0; k < 3; ++k) {if (color[3 * j + k] == 3)face[3 * j + k] = 9;else if (color[3 * j + k] == 4)face[3 * j + k] = 10;else face[3 * j + k] = 11;}}break;case 3: {for (int k = 0; k < 3; ++k) {if (color[3 * j + k] == 1)face[3 * j + k] = 12;else if (color[3 * j + k] == 2)face[3 * j + k] = 13;else face[3 * j + k] = 14;}}break;case 7: {for (int k = 0; k < 3; ++k) {if (color[3 * j + k] == 1)face[3 * j + k] = 15;else if (color[3 * j + k] == 4)face[3 * j + k] = 16;else face[3 * j + k] = 17;}}break;case 6: {for (int k = 0; k < 3; ++k) {if (color[3 * j + k] == 1)face[3 * j + k] = 18;else if (color[3 * j + k] == 0)face[3 * j + k] = 19;else face[3 * j + k] = 20;}}break;case 10: {for (int k = 0; k < 3; ++k) {if (color[3 * j + k] == 1)face[3 * j + k] = 21;else if (color[3 * j + k] == 5)face[3 * j + k] = 22;else face[3 * j + k] = 23;}}}}
}
uint64 F_plus(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[2]; arr[2] = arr[8]; arr[8] = arr[11]; arr[11] = arr[5]; arr[5] = temp;temp = arr[4]; arr[4] = arr[1]; arr[1] = arr[7]; arr[7] = arr[10]; arr[10] = temp;temp = arr[0]; arr[0] = arr[6]; arr[6] = arr[9]; arr[9] = arr[3]; arr[3] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
uint64 F_double(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[2]; arr[2] = arr[11]; arr[11] = temp;temp = arr[5]; arr[5] = arr[8]; arr[8] = temp;temp = arr[4]; arr[4] = arr[7]; arr[7] = temp;temp = arr[1]; arr[1] = arr[10]; arr[10] = temp;temp = arr[0]; arr[0] = arr[9]; arr[9] = temp;temp = arr[3]; arr[3] = arr[6]; arr[6] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
uint64 F_minus(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[2]; arr[2] = arr[5]; arr[5] = arr[11]; arr[11] = arr[8]; arr[8] = temp;temp = arr[4]; arr[4] = arr[10]; arr[10] = arr[7]; arr[7] = arr[1]; arr[1] = temp;temp = arr[0]; arr[0] = arr[3]; arr[3] = arr[9]; arr[9] = arr[6]; arr[6] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
uint64 R_plus(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[3]; arr[3] = arr[11]; arr[11] = arr[21]; arr[21] = arr[17]; arr[17] = temp;temp = arr[4]; arr[4] = arr[9]; arr[9] = arr[22]; arr[22] = arr[15]; arr[15] = temp;temp = arr[5]; arr[5] = arr[10]; arr[10] = arr[23]; arr[23] = arr[16]; arr[16] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
uint64 R_double(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[3]; arr[3] = arr[21]; arr[21] = temp;temp = arr[11]; arr[11] = arr[17]; arr[17] = temp;temp = arr[4]; arr[4] = arr[22]; arr[22] = temp;temp = arr[9]; arr[9] = arr[15]; arr[15] = temp;temp = arr[5]; arr[5] = arr[23]; arr[23] = temp;temp = arr[10]; arr[10] = arr[16]; arr[16] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
uint64 R_minus(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[3]; arr[3] = arr[17]; arr[17] = arr[21]; arr[21] = arr[11]; arr[11] = temp;temp = arr[4]; arr[4] = arr[15]; arr[15] = arr[22]; arr[22] = arr[9]; arr[9] = temp;temp = arr[5]; arr[5] = arr[16]; arr[16] = arr[23]; arr[23] = arr[10]; arr[10] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
uint64 U_plus(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[0]; arr[0] = arr[5]; arr[5] = arr[15]; arr[15] = arr[14]; arr[14] = temp;temp = arr[1]; arr[1] = arr[3]; arr[3] = arr[16]; arr[16] = arr[12]; arr[12] = temp;temp = arr[2]; arr[2] = arr[4]; arr[4] = arr[17]; arr[17] = arr[13]; arr[13] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
uint64 U_double(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[0]; arr[0] = arr[15]; arr[15] = temp;temp = arr[5]; arr[5] = arr[14]; arr[14] = temp;temp = arr[1]; arr[1] = arr[16]; arr[16] = temp;temp = arr[3]; arr[3] = arr[12]; arr[12] = temp;temp = arr[2]; arr[2] = arr[17]; arr[17] = temp;temp = arr[4]; arr[4] = arr[13]; arr[13] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
uint64 U_minus(uint64 s) {int * arr = new int[24];decode(s, arr);int temp;temp = arr[0]; arr[0] = arr[14]; arr[14] = arr[15]; arr[15] = arr[5]; arr[5] = temp;temp = arr[1]; arr[1] = arr[12]; arr[12] = arr[16]; arr[16] = arr[3]; arr[3] = temp;temp = arr[2]; arr[2] = arr[13]; arr[13] = arr[17]; arr[17] = arr[4]; arr[4] = temp;uint64 s_new = encode(arr);delete arr;return s_new;
};
void dbfs(station &start, station &end) {if (start->code == end->code)  return;start->dir = 0;end->dir = 1;queue <station> Qs, Qe;Qs.push(start);Qe.push(end);visited.insert(pair<uint64, station>(start->code, start));visited.insert(pair<uint64, station>(end->code, end));while (!Qs.empty() || !Qe.empty()) {if (!Qs.empty()) {station left = Qs.front();Qs.pop();uint64 s[9] = { 0 };if (left->operate >= 0 && left->operate <= 2) {s[3] = R_plus(left->code), s[4] = R_double(left->code), s[5] = R_minus(left->code);s[6] = U_plus(left->code), s[7] = U_double(left->code), s[8] = U_minus(left->code);}else if (left->operate >= 3 && left->operate <= 5) {s[0] = F_plus(left->code), s[1] = F_double(left->code), s[2] = F_minus(left->code);s[6] = U_plus(left->code), s[7] = U_double(left->code), s[8] = U_minus(left->code);}else if (left->operate >= 6 && left->operate <= 8) {s[0] = F_plus(left->code), s[1] = F_double(left->code), s[2] = F_minus(left->code);s[3] = R_plus(left->code), s[4] = R_double(left->code), s[5] = R_minus(left->code);}else {s[0] = F_plus(left->code), s[1] = F_double(left->code), s[2] = F_minus(left->code);s[3] = R_plus(left->code), s[4] = R_double(left->code), s[5] = R_minus(left->code);s[6] = U_plus(left->code), s[7] = U_double(left->code), s[8] = U_minus(left->code);}for (int i = 0; i < 9; ++i) {if (s[i] != 0) {if (visited.count(s[i])) {station right = visited.find(s[i])->second;int flag = right->dir;if (flag == 0)  continue;if (flag == 1) {station branch = new Station();branch->code = s[i];branch->step = left->step + 1;branch->dir = 0;branch->operate = i;branch->father = left;start = branch; end = right;return;}}else {station branch = new Station();branch->code = s[i];branch->step = left->step + 1;branch->dir = 0;branch->operate = i;branch->father = left;Qs.push(branch);visited.insert(pair<uint64, station>(s[i], branch));}}}}if (!Qe.empty()) {station right = Qe.front();Qe.pop();uint64 s[9] = { 0 };if (right->operate >= 0 && right->operate <= 2) {s[3] = R_minus(right->code), s[4] = R_double(right->code), s[5] = R_plus(right->code);s[6] = U_minus(right->code), s[7] = U_double(right->code), s[8] = U_plus(right->code);}else if (right->operate >= 3 && right->operate <= 5) {s[0] = F_minus(right->code), s[1] = F_double(right->code), s[2] = F_plus(right->code);s[6] = U_minus(right->code), s[7] = U_double(right->code), s[8] = U_plus(right->code);}else if (right->operate >= 6 && right->operate <= 8) {s[0] = F_minus(right->code), s[1] = F_double(right->code), s[2] = F_plus(right->code);s[3] = R_minus(right->code), s[4] = R_double(right->code), s[5] = R_plus(right->code);}else {s[0] = F_minus(right->code), s[1] = F_double(right->code), s[2] = F_plus(right->code);s[3] = R_minus(right->code), s[4] = R_double(right->code), s[5] = R_plus(right->code);s[6] = U_minus(right->code), s[7] = U_double(right->code), s[8] = U_plus(right->code);}for (int i = 0; i < 9; ++i) {if (s[i] != 0) {if (visited.count(s[i])) {station left = visited.find(s[i])->second;int flag = left->dir;if (flag == 1)  continue;if (flag == 0) {station branch = new Station();branch->code = s[i];branch->step = right->step + 1;branch->dir = 1;branch->father = right;branch->operate = i;start = left; end = branch;return;}}else {station branch = new Station();branch->code = s[i];branch->step = right->step + 1;branch->dir = 1;branch->father = right;branch->operate = i;Qe.push(branch);visited.insert(pair<uint64, station>(s[i], branch));}}}}}
}int main() {   int i, j;station Start = new Station();station End = new Station();int arr1[24] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 };End->code = encode(arr1);int arr2[24];for (i = 0; i < 24; ++i) scanf("%d", &arr2[i]);Start->code = encode(arr2);dbfs(Start, End);int lStep = Start->step, rStep = End->step;int Step = lStep + rStep;printf("%d\n", Step);int Operate[12],Face[12][24];for (i = 0; Start->father != NULL; ++i) {Operate[lStep - i - 1] = Start->operate;decode(Start->code, Face[lStep - i - 1]);Start = Start->father;}for (i = 0; End->father != NULL; ++i) {Operate[lStep + i] = End->operate;decode(End->father->code, Face[lStep + i]);End = End->father;}for (i = 0; i < Step; ++i) {switch (Operate[i]) {case 0:printf("F+\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); break;case 1:printf("F2\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); break;case 2:printf("F-\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); break;case 3:printf("R+\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); break;case 4:printf("R2\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); break;case 5:printf("R-\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); break;case 6:printf("U+\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); break;case 7:printf("U2\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); break;case 8:printf("U-\n"); for (j = 0; j < 24; ++j)printf("%d ", Face[i][j]); printf("\n"); }}return 0;
}

【二阶魔方还原】第十次OJ的总结相关推荐

  1. 二阶魔方还原 Rubik’s Cube 双向广度优先搜索

    1. 算法简介 使用搜索算法完成二阶魔方从任意初始状态向目标状态的操作转换.         根据已有的研究,二阶魔方的上帝之数为11(进行FTM计数)或14(进行QTM计数),本算法采用QTM计数对 ...

  2. 二阶魔方的最少步打乱 Apare_xzc

    二阶魔方的最少步打乱 Apare_xzc 2020.2.20 13:17 前言: 博主xzc是一个魔方爱好者,三阶sub 25s.虽然水平不高,但是对魔方十分热爱.博主对二阶魔方编码,然后通过bfs得 ...

  3. 【项目实践】二阶魔方搜索算法

    前言   课程<智能控制基础>课后作业要求编写一个二阶魔方搜素求解的算法,由于本人的代码水平真的不行,只能"面向互联网编程",前前后后找了不少资料,也确实学习到一点东西 ...

  4. 利用BFS广度优先搜索还原二阶魔方

    利用BFS广度优先搜索还原二阶魔方 采用BFS深度优先搜索算法进行了对于魔方求解问题的建模,并且利用C++代码进行了算法实现,能够实现输入魔方状态,自动输出解法的效果. BFS是图论中一种基本的搜索算 ...

  5. 二阶魔方 三阶魔方还原法

    二阶魔方 三阶魔方还原法  二阶魔方归正: 1 下面蓝色  不停用 上右下左,直到下面全蓝 2 翻动蓝色到上方,  找到左右的上侧 两个相同的颜色固定 ,然后  上右下推  上右下左 下压上 上左下左 ...

  6. 魔方还原神器,有了它,没有还原不了的魔方(15)

    小朋友们好,大朋友们好! 我是猫妹,一名爱上Python编程的小学生. 欢迎和猫妹一起,趣味学Python. 今日主题 今天呢,我们学习一点关于魔方的知识. 魔方,又叫鲁比克方块,最早是由匈牙利布达佩 ...

  7. python解魔方程序_写一个解二阶魔方的程序

    本文需要读者有一定的魔方基础, 最起码也要达到十秒内还原二阶魔方的水平, 并且手上最好有一个二阶魔方, 否则文中的很多东西理解不了. 另外, 这里使用的算法是我自己写着玩的, 如果你需要更成熟和专业的 ...

  8. DBFS解二阶魔方——一次c++学习之旅

    目录 前言 构思解法 优化方案 代码及详细注释 1.定义魔方的一个状态 2.状态初始化 3.转动 4.查重 5.双向广搜 6.输出 7.输入 8.主函数 几段实用代码 前言 本人是c++初学者,对魔方 ...

  9. 二阶魔方复原算法推算-Part1

    (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 1. 二阶魔方 对于魔方来说,二阶魔方算是比较简单的,共有8个顶角块,上面四个块,下面四个块:可以分为 ...

最新文章

  1. 是什么阻碍了你的 AI 致富路?
  2. wordpress房产信息网_Realia v3.1.2 wordpress房地产模板 租房网站模板
  3. linux sudo 版本,Linu下如何升级当前sudo版本
  4. linux-文件类型与查看文件型
  5. Revit二次开发之“为Ribbon设置快捷键”
  6. C++中struct和class的区别 [zz]
  7. paip.php eclipse output echo 乱码
  8. 计算机组成原理第六版课后题答案pdf,数据库第五版课后答案pdf
  9. MSC-51单片机原理与实践——第四章习题及答案解析
  10. 这是一篇关于如何成为一名AI算法工程师的长文
  11. linux局域网即时通讯,基于身份的Linux下局域网即时通讯系统的研究与实现
  12. 红蓝出屏3D图片,请使用红蓝眼镜观看
  13. 美术 2.7 Metallic与Speculer流程
  14. C++中的开辟/释放动态空间new/delete
  15. python开源电子书_Python 开源电子书资源
  16. 西安市版权申请代理公司怎么选,哪些类型作品受版权保护?
  17. 【调剂】北京外国语大学人工智能与人类语言重点实验室2022年全国研招统考拟接收调剂公告...
  18. CSS-div水平居左-居右-居中显示
  19. MTK5G-MT6853(天玑720)
  20. 1.4 高级数据库系统

热门文章

  1. 计蒜客 T1895切蛋糕(单调队列)
  2. 机器人行业未来走势如何?这有「30+2」篇研究报告全方位剖析
  3. oracle9i连不上10g,oracle 10g客户端连接oracle 9i数据库
  4. vue实现消息badge 标记_一天一个 Element 组件 - Badge
  5. 小胖虎带你们了解MySQL中的连接查询
  6. 嵌入式c语言开发闹钟,嵌入式电子闹钟()时钟课程设计.doc
  7. 基于Linux下的服务器搭建(网络编程)
  8. 网上点餐系统数据库表
  9. 项目经验-创新谈-张建伟
  10. android photoview 图片放大缩放功能 ImageView