魔⽅还原代码python_如何⽤C语⾔还原三阶魔⽅?
本答案由3部分组成。第⼀部分是最早看到题⽬时我的想法。第⼆部分是我调研了⼀圈现有程序之后提出的我觉得⽐较暴⼒的解法,并附上C语⾔源代码。第三部分补充了⼀些思考,这部分会有少量魔⽅术语,如看不懂可以直接作为专业名词跳过即可。
根据经验,如果你没有玩过魔⽅,那么最简单的步骤是:先学会复原魔⽅。或者如果觉得背公式太烦,⾄少能够在看着教程的基础上⼀步⼀步跟着教程复原魔⽅。
把教程的每个步骤⽤C语⾔写出来。
其实有很多更简单粗暴有效的还原⽅法,但那些⽅法通常要求你对魔⽅有着更深刻的认识,可能会花费你更多的时间,并且更难调试。
==========分割线==========
花了⼤约半个晚上调研了⼀下百度到的各种C语⾔解魔⽅的程序,基本上还真都是层先法的计算机实现。讲道理,层先法是⽤来给⼈学的,⽤C语⾔实现⾃然不会有什么难点,只是⾮常繁琐,需要输⼊各种公式,做各种繁琐的状态判断。于是我决定不讲道理,⽤暴⼒流另辟蹊径。给题主提供⼀个完全不⼀样的思路。
具体算法思路如下:
每次随机做公式,检查还有多少个块没有好,如果⽐做公式之前少,则更新状态,否则推倒重来,继续随机做公式,直到还原。其中,我把棱块的优先级调整的⽐⾓块更⾼,主要是为了省事。
每次做的公式由以下三部分组成随机转5步。
随机选取3个转动,如A,B,C。构造如下公式:A B A' C A B' A' C'。然后做这个公司或其任意位置开始的循环8步,如B' A' C' A B A' C A等。其中带“'”代表逆转动。
转第1部分的逆序。
实测表明,⼤部分状态都能秒出解。有些状态会卡在两⾓翻,不过卡⼀会⼉了以后基本也能最终解出来。当然解法肯定⽐较长,但相信我,相⽐别的算法,这个算法更容易实现,你甚⾄都不需要会还原魔⽅。
源代码如下。注释并不多,核⼼算法写在了void solve(int *)函数⾥,别的各种函数⽤来辅助。魔⽅的存储⽅式是直接⽤⼀个54长的数组来存魔⽅表⾯每⼀⽚的颜⾊,于是魔⽅的转动就变成了对数组的置换操作。剩下的就是在这样简单的数据结构上实现我说的暴⼒流算法了。
#include
#include
#include
// cube definition:
//
// |************|
// |*U1**U2**U3*|
// |************|
// |*U4**U5**U6*|
// |************|
// |*U7**U8**U9*|
// |************|
/
/ ************|************|************|************|
// *L1**L2**L3*|*F1**F2**F3*|*R1**R2**R3*|*B1**B2**B3*|
// ************|************|************|************|
// *L4**L5**L6*|*F4**F5**F6*|*R4**R5**R6*|*B4**B5**B6*|
// ************|************|************|************|
// *L7**L8**L9*|*F7**F8**F9*|*R7**R8**R9*|*B7**B8**B9*|
// ************|************|************|************|
// |************|
// |*D1**D2**D3*|
// |************|
// |*D4**D5**D6*|
/
/ |************|
// |*D7**D8**D9*|
// |************|
//
// ->
U1U2U3U4U5U6U7U8U9R1R2R3R4R5R6R7R8R9F1F2F3F4F5F6F7F8F9D1D2D3D4D5D6D7D8D9L1L2L3L4L5L6L7L8L9B1B2
const int U1 = 0, U2 = 1, U3 = 2, U4 = 3, U5 = 4, U6 = 5, U7 = 6, U8 = 7, U9 = 8,
R1 = 9, R2 = 10, R3 = 11, R4 = 12, R5 = 13, R6 = 14, R7 = 15, R8 = 16, R9 = 17,
F1 = 18, F2 = 19, F3 = 20, F4 = 21, F5 = 22, F6 = 23, F7 = 24, F8 = 25, F9 = 26,
D1 = 27, D2 = 28, D3 = 29, D4 = 30, D5 = 31, D6 = 32, D7 = 33, D8 = 34, D9 = 35,
L1 = 36, L2 = 37, L3 = 38, L4 = 39, L5 = 40, L6 = 41, L7 = 42, L8 = 43, L9 = 44,
B1 = 45, B2 = 46, B3 = 47, B4 = 48, B5 = 49, B6 = 50, B7 = 51, B8 = 52, B9 = 53;
const char *move2str[18] = {
"U", "U2", "U'",
"R", "R2", "R'",
"F", "F2", "F'",
"D", "D2", "D'",
"L", "L2", "L'",
"B", "B2", "B'"
};
const int PRE_MOVE_LENGTH = 5;
/
/ cube[idx1] -> cube[idx2] -> cube[idx3] -> cube[idx4] -> cube[idx1], rep+1 times
void swap4(int *cube, int idx1, int idx2, int idx3, int idx4, int rep) {
int tmp;
for (int i = 0; i <= rep; ++i) {
tmp = cube[idx4];
cube[idx4] = cube[idx3];
cube[idx3] = cube[idx2];
cube[idx2] = cube[idx1];
cube[idx1] = tmp;
}
}
/
/move = axis * 3 + power
//axis: U=0, R=1, F=2, D=3, L=4, B=5
//power: 0=clockwise, 1=180 degrees, 2=anti-clockwise void doMove(int *cube, int move) {
int tmp;
int axis = move / 3;
int power = move % 3;
switch (axis) {
case 0:
swap4(cube, U1, U3, U9, U7, power);
swap4(cube, U2, U6, U8, U4, power);
swap4(cube, F1, L1, B1, R1, power);
swap4(cube, F2, L2, B2, R2, power);
swap4(cube, F3, L3, B3, R3, power);
break;
case 1:
swap4(cube, R1, R3, R9, R7, power);
swap4(cube, R2, R6, R8, R4, power);
swap4(cube, U3, B7, D3, F3, power);
swap4(cube, U6, B4, D6, F6, power);
swap4(cube, U9, B1, D9, F9, power);
break;
case 2:
swap4(cube, F1, F3, F9, F7, power);
swap4(cube, F2, F6, F8, F4, power);
swap4(cube, U7, R1, D3, L9, power);
swap4(cube, U8, R4, D2, L6, power);
swap4(cube, U9, R7, D1, L3, power);
break;
case 3:
swap4(cube, D1, D3, D9, D7, power); swap4(cube, D2, D6, D8, D4, power); swap4(cube, F7, R7, B7, L7, power); swap4(cube, F8, R8, B8, L8, power); swap4(cube, F9, R9, B9, L9, power); break;
case 4:
swap4(cube, L1, L3, L9, L7, power); swap4(cube, L2, L6, L8, L4, power); swap4(cube, U1, F1, D1, B9, power); swap4(cube, U4, F4, D4, B6, power); swap4(cube, U7, F7, D7, B3, power); break;
case 5:
swap4(cube, B1, B3, B9, B7, power); swap4(cube, B2, B6, B8, B4, power); swap4(cube, U3, L1, D7, R9, power); swap4(cube, U2, L4, D8, R6, power); swap4(cube, U1, L7, D9, R3, power); break;
编程先学c语言还是python}
}
int distance(int *cube1, int *cube2) { int distanceEdge = 0;
int distanceCorn = 0;
for (int i = 0; i < 54; ++i) {
if (cube1[i] == cube2[i]) {
continue;
}
if (i % 9 % 2 == 0) {
distanceCorn++;
} else {
distanceEdge++;
}
}
return distanceEdge * 100 + distanceCorn;
}
void copyCube(int *dist, const int *src) {
for (int i = 0; i < 54; ++i) {
dist[i] = src[i];
}
}
void initSolvedCube(int *cube) {
for (int i = 0; i < 54; ++i) {
cube[i] = i / 9;
}
}
int invMove(int move) {
return move / 3 * 3 + 2 - move % 3;
}
void solve(int *cube) {
int solvedCube[54];
int cubeTmp[54];
int algMoves[8];
int preMoveList[PRE_MOVE_LENGTH];
int algStartIdx;
initSolvedCube(solvedCube);
int curDistance = distance(cube, solvedCube); int tmpDistance;
while (curDistance != 0) {
copyCube(cubeTmp, cube);
if (curDistance / 100 == 2) { //odd parity doMove(cubeTmp, 0);
printf("U ");
curDistance = 10000;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论