Herbert Kociemba algorithm(计算机求解三阶魔方)

代码转载自:Herbert Kociemba algorithm(计算机求解三阶魔方)(1000行完整版) - 哔哩哔哩

#include<iostream>
#include <string>

using namespace std;

typedef enum { URF, UFL, ULB, UBR, DFR, DLF, DBL, DRB } Corner;
typedef enum { UR, UF, UL, UB, DR, DF, DL, DB, FR, FL, BL, BR } Edge;
typedef enum direc { U, D, L, R, F, B } fangxiang;

struct corner//角块 
{
	Corner c;
	int o;
};

struct edge//棱块 
{
	Edge e;
	int o;
};

struct corner1//角块带色相 
{
	Corner c;
	int color[3];
	int o;
};

struct edge1//棱块带色相 
{
	Edge e;
	int color[2];
	int o;
};

struct Cube//魔方状态 
{
	corner co[8];
	edge eo[12];
};

struct Cube1//魔方状态带色相 
{
	corner1 co1[8];
	edge1 eo1[12];
};

Cube Move[6];
Cube initc;

int idcornero(Cube x)//角块方向编码 
{
	int idco = 0;
	for (Corner c = URF; c < DRB; c = Corner(int(c) + 1))
	{
		idco = 3 * idco + x.co[c].o;
	}
	return idco;
}

int idedgeo(Cube x)//棱块方向编码
{
	int ideo = 0;
	for (Edge c = UR; c < BR; c = Edge(int(c) + 1))
	{
		ideo = 2 * ideo + x.eo[c].o;
	}
	return ideo;
}

int idcornerp(Cube x)//角块位置排列编码 
{
	int idcp = 0;
	for (int i = DRB; i > URF; i--) 
	{
		int s = 0;
		for (int j = i - 1; j >= URF; j--)
		{
			if (x.co[j].c > x.co[i].c)
			{
				s++;
			}
		}
		idcp = (idcp + s) * i;
	}
	return idcp;
}

int idedgep(Cube x)//上下层棱块位置排列编码 
{

	int idep = 0;

	for (int i = DB; i > UR; i--) 
	{
		int s = 0;
		for (int j = i - 1; j >= UR; j--)
		{
			if (x.eo[j].e > x.eo[i].e)
			{
				s++;
			}
		}
		idep = (idep + s) * i;
	}
	return idep;
}

int idedgez(Cube x)//中间层棱块位置排列编码 
{
	int idez = 0;
	for (int i = BR; i > FR; i--) 
	{
		int s = 0;
		for (int j = i - 1; j >= FR; j--)
		{
			if (x.eo[j].e > x.eo[i].e)
			{
				s++;
			}
		}
		idez = (idez + s) * (i - 8);
	}
	return idez;
}

int jie[10] = { 1,1,2,6,24,120,720,5040,40320,362880 };

Cube paijiao(int x)
{
	Cube a; 
	int pan[8] = { 0,0,0,0,0,0,0,0 };
	for (int i = 7; i >= 0; i--)
	{
		int s = x / jie[i];
		x = x % jie[i];
		int shu = s + 1;
		for (int j = 7; j >= 0; j--)
		{
			if (pan[j] == 1)
			{
				continue;
			}
			shu--;
			if (shu == 0)
			{
				a.co[i].c = Corner(j);
				pan[j] = 1;
			}
		}
	}
	return a;
}

Cube paileng1(int x)
{
	Cube a; int pan[8] = { 0,0,0,0,0,0,0,0 };
	for (int i = 7; i >= 0; i--)
	{
		int s = x / jie[i]; 
		x = x % jie[i]; 
		int shu = s + 1;
		for (int j = 7; j >= 0; j--)
		{
			if (pan[j] == 1)
			{
				continue;
			}
			shu--;
			if (shu == 0)
			{
				a.eo[i].e = Edge(j);
				pan[j] = 1;
			}
		}
	}
	for (int i = 8; i <= 11; i++)
	{
		a.eo[i].e = Edge(i);
	}
	return a;
}

Cube paileng2(int x)
{
	Cube a; 
	int pan[4] = { 0,0,0,0 };
	for (int i = 3; i >= 0; i--)
	{
		int s = x / jie[i];
		x = x % jie[i];
		int shu = s + 1;
		for (int j = 3; j >= 0; j--)
		{
			if (pan[j] == 1)
			{
				continue;
			}
			shu--;
			if (shu == 0)
			{
				a.eo[8 + i].e = Edge(8 + j);
				pan[j] = 1;
			}
		}
	}
	for (int i = 0; i <= 7; i++)
	{
		a.eo[i].e = Edge(i);
	}
	return a;
}

int C[12][5] =//组合数表 
{

	400,0,0,0,0,

	1,1,0,0,0,

	1,2,1,0,0,

	1,3,3,1,0,

	1,4,6,4,1,

	1,5,10,10,5,

	1,6,15,20,15,

	1,7,21,35,35,

	1,8,28,56,70,

	1,9,36,84,126,

	1,10,45,120,210,

	1,11,55,165,330,

};

int idslice(Cube x)//中间层四个块的位置编码 
{
	int ids = 0, y = 0;
	for (int i = BR; i >= UR; i--)
	{
		if (x.eo[i].e >= FR && x.eo[i].e <= BR)
		{
			ids += C[11 - i][y + 1];
			y++;
		}
	}
	return ids;
}

Cube slicecube(int x)//棱块组合数由编码变块层 
{
	Cube a; 
	int y = 4;
	for (int i = 0; i <= 11; i++)
	{
		a.eo[i].e = Edge(0);
	}
	for (int i = UR; i <= BR; i++)
	{
		if (x >= C[11 - i][y])
		{
			a.eo[i].e = Edge(12 - y);
			x -= C[11 - i][y];
			y--;
		}
	}//cout<<x<<endl;
	return a;
}

Cube twistcube(int x)//角块方向,坐标层次到块层次的转换
{
	Cube a; int tmp = 0;
	for (Corner c = DBL; c >= URF; c = Corner(int(c) - 1))
	{
		a.co[c].o = x % 3; 
		tmp = (x % 3 + tmp) % 3; 
		x /= 3;
	}
	a.co[DRB].o = 3 - tmp;
	return a;
}

Cube flipcube(int x)//棱边方向,坐标层次到块层次的转换 
{
	Cube a; 
	int tmp = 0;
	for (Edge c = BL; c >= UR; c = Edge(int(c) - 1))
	{
		a.eo[c].o = x % 2; 
		tmp = (x % 2 + tmp) % 2; 
		x /= 2;
	}
	a.eo[BR].o = 2 - tmp;
	return a;
}

void cornerMultiply(const Cube* a, const Cube* b, Cube* ab)//角块的方向和位置 
{
	for (Corner i = URF; i <= DRB; i = Corner(int(i) + 1))
	{
		ab->co[i].c = a->co[b->co[i].c].c;
		ab->co[i].o = (a->co[b->co[i].c].o + b->co[i].o) % 3;
	}
	return;
}

void edgeMultiply(const Cube* a, const Cube* b, Cube* ab)//棱块的方向和位置 
{
	for (Edge i = UR; i <= BR; i = Edge(int(i) + 1))
	{
		ab->eo[i].e = a->eo[b->eo[i].e].e;
		ab->eo[i].o = (a->eo[b->eo[i].e].o + b->eo[i].o) % 2;
	}
	return;
}

void edgeMultiply1(const Cube* a, const Cube* b, Cube* ab)//棱块的方向和位置 
{
	for (Edge i = UR; i <= BR; i = Edge(int(i) + 1))
	{
		ab->eo[i].e = a->eo[b->eo[i].e].e;
	}
	return;
}

Cube cubeMove(Cube cc, int m)//转动函数 
{
	Cube ccret;
	cornerMultiply(&cc, &Move[m], &ccret);
	edgeMultiply(&cc, &Move[m], &ccret);
	return ccret;
}

struct caozuo
{
	direc a;
	int b;
};

caozuo cz[10] = { {U,0},{U,1},{U,2},{D,0},{D,1},{D,2},{L,1},{R,1},{F,1},{B,1} };

const int NTWIST = 2187;
const int NFLIP = 2048;
const int NSLICE = 495;
const int Nmove = 18;
const int NCP = 40320;
const int NEP1 = 40320;
const int NEP2 = 24;

int twistMoveTable[NTWIST][Nmove];
int flipMoveTable[NFLIP][Nmove];
int sliceMoveTable[NSLICE][Nmove];
int cpMoveTable[NCP][Nmove];
int epMoveTable1[NEP1][Nmove];
int epMoveTable2[NEP2][Nmove];

void initcpMoveTable()
{
	Cube a, b;
	int i, j, m;
	for (int i = 0; i <= NCP - 1; i++)
	{
		a = paijiao(i);
		for (int j = U; j <= B; j++) 
		{
			for (int k = 0; k < 3; k++) 
			{
				cornerMultiply(&a, &Move[j], &b);
				a = b;
				cpMoveTable[i][j * 3 + k] = idcornerp(b);
			}
			cornerMultiply(&a, &Move[j], &b); 
			a = b; //cout<<idcornero(b)<<endl;
		}
	}
	return;
}

void initepMoveTable1()
{
	Cube a, b;
	int i, j, m;
	for (int i = 0; i <= NEP1 - 1; i++)
	{
		a = paileng1(i);
		for (int j = U; j <= B; j++) 
		{
			for (int k = 0; k < 3; k++) 
			{
				edgeMultiply(&a, &Move[j], &b);
				a = b;
				epMoveTable1[i][j * 3 + k] = idedgep(b);
			}
			edgeMultiply(&a, &Move[j], &b); 
			a = b; //cout<<idcornero(b)<<endl;
		}
	}
	return;
}

void initepMoveTable2()
{
	Cube a, b;
	int i, j, m;
	for (int i = 0; i <= NEP2 - 1; i++)
	{
		a = paileng2(i);
		for (int j = U; j <= B; j++) 
		{
			for (int k = 0; k < 3; k++) 
			{
				edgeMultiply(&a, &Move[j], &b);
				a = b;//cout<<idedgez(a)<<endl;
				epMoveTable2[i][j * 3 + k] = idedgez(b);
			}
			edgeMultiply(&a, &Move[j], &b); a = b; //cout<<idcornero(b)<<endl;
		}
	}
	return;
}

void initSliceMoveTable()//初始化中间棱块位置组合转动表 
{
	Cube a, b;
	int i, j, m;
	for (int i = 0; i <= NSLICE - 1; i++)
	{
		a = slicecube(i);
		for (int j = U; j <= B; j++) 
		{
			for (int k = 0; k < 3; k++) 
			{
				edgeMultiply(&a, &Move[j], &b);
				a = b;
				sliceMoveTable[i][j * 3 + k] = idslice(b);
			}
			edgeMultiply(&a, &Move[j], &b); 
			a = b; //cout<<idcornero(b)<<endl;
		}
	}
	return;
}

void initTwistMoveTable()//初始化角块方向转动表 
{
	Cube a, b;
	int i, j, m;
	for (int i = 0; i <= NTWIST - 1; i++)
	{
		a = twistcube(i);
		for (int j = U; j <= B; j++) 
		{
			for (int k = 0; k < 3; k++) 
			{
				cornerMultiply(&a, &Move[j], &b);
				a = b;
				twistMoveTable[i][j * 3 + k] = idcornero(b);
			}
			cornerMultiply(&a, &Move[j], &b); a = b; //cout<<idcornero(b)<<endl;
		}
	}
	return;
}

void initFlipMoveTable()//初始化棱块方向转动表 
{
	Cube a, b;
	int i, j, m;
	for (int i = 0; i <= NFLIP - 1; i++)
	{
		a = flipcube(i);
		for (int j = U; j <= B; j++) 
		{
			for (int k = 0; k < 3; k++) 
			{
				edgeMultiply(&a, &Move[j], &b);
				a = b;
				flipMoveTable[i][j * 3 + k] = idedgeo(b);
			}
			edgeMultiply(&a, &Move[j], &b);
			a = b; //cout<<idcornero(b)<<endl;
		}
	}
	return;
}

int PruneTable1[NTWIST];
int PruneTable2[NFLIP];
int PruneTable3[NSLICE];
int PruneTable4[NCP];
int PruneTable5[NEP1];
int PruneTable6[NEP2];

void initPruneTable1()//角块方向的剪枝表 
{
	for (int i = 0; i <= NTWIST - 1; i++)
	{
		PruneTable1[i] = -1;
	}
	int depth = 0;
	PruneTable1[0] = 0;
	int done = 1;
	int index;
	while (done < NTWIST)
	{
		for (int i = 0; i < NTWIST; i++)
		{
			if (PruneTable1[i] == depth)
			{
				for (int j = 0; j <= 17; j++)
				{
					index = twistMoveTable[i][j];
					if (PruneTable1[index] == -1)
					{
						PruneTable1[index] = depth + 1;
						done++;
					}
				}
			}
		}
		depth++;//cout<<done<<endl;
	}
	return;
}

void initPruneTable2()//棱块方向的剪枝表 
{
	for (int i = 0; i <= NFLIP - 1; i++)
	{
		PruneTable2[i] = -1;
	}
	int depth = 0;
	PruneTable2[0] = 0;
	int done = 1; int index;
	while (done < NFLIP)
	{
		for (int i = 0; i < NFLIP; i++)
		{
			if (PruneTable2[i] == depth)
			{
				for (int j = 0; j <= 17; j++)
				{
					index = flipMoveTable[i][j];
					if (PruneTable2[index] == -1)
					{
						PruneTable2[index] = depth + 1;
						done++;
					}
				}
			}
		}
		depth++;//cout<<done<<endl;
	}
	return;
}

void initPruneTable3()//棱块位置组合的剪枝表 
{
	for (int i = 0; i <= NSLICE - 1; i++)
	{
		PruneTable3[i] = -1;
	}
	int depth = 0;
	PruneTable3[0] = 0;
	int done = 1; 
	int index;
	while (done < NSLICE)
	{
		for (int i = 0; i < NSLICE; i++)
		{
			if (PruneTable3[i] == depth)
			{
				for (int j = 0; j <= 17; j++)
				{
					index = sliceMoveTable[i][j];
					if (PruneTable3[index] == -1)
					{
						PruneTable3[index] = depth + 1;
						done++;
					}
				}
			}
		}
		depth++;//cout<<done<<endl;
	}
	return;
}

void initPruneTable4()//角块位置的剪枝表 
{
	for (int i = 0; i <= NCP - 1; i++)
	{
		PruneTable4[i] = -1;
	}
	int depth = 0;
	PruneTable4[0] = 0;
	int done = 1; int index;
	while (done < NCP)
	{
		for (int i = 0; i < NCP; i++)
		{
			if (PruneTable4[i] == depth)
			{
				for (int j = 0; j < 10; j++)
				{
					int x = cz[j].a;
					int y = cz[j].b;
					index = cpMoveTable[i][x * 3 + y];
					if (PruneTable4[index] == -1)
					{
						PruneTable4[index] = depth + 1;
						done++;
					}
				}
			}
		}
		depth++;//cout<<done<<endl;
	}
	return;
}

void initPruneTable5()//上下层棱块位置的剪枝表 
{
	for (int i = 0; i <= NEP1 - 1; i++)
	{
		PruneTable5[i] = -1;
	}
	int depth = 0;
	PruneTable5[0] = 0;
	int done = 1; int index;
	while (done < NEP1)
	{
		for (int i = 0; i < NEP1; i++)
		{
			if (PruneTable5[i] == depth)
			{
				for (int j = 0; j < 10; j++)
				{
					int x = cz[j].a;
					int y = cz[j].b;
					index = epMoveTable1[i][x * 3 + y];
					if (PruneTable5[index] == -1)
					{
						PruneTable5[index] = depth + 1;
						done++;
					}
				}
			}
		}
		depth++;//cout<<done<<endl;
	}
	return;
}

void initPruneTable6()//中层棱块位置的剪枝表 
{
	for (int i = 0; i <= NEP2 - 1; i++)
	{
		PruneTable6[i] = -1;
	}
	int depth = 0;
	PruneTable6[0] = 0;
	int done = 1; int index;
	while (done < NEP2)
	{
		for (int i = 0; i < NEP2; i++)
		{
			if (PruneTable6[i] == depth)
			{
				for (int j = 0; j < 10; j++)
				{
					int x = cz[j].a;
					int y = cz[j].b;
					index = epMoveTable2[i][x * 3 + y];
					if (PruneTable6[index] == -1)
					{
						PruneTable6[index] = depth + 1;
						done++;
					}
				}
			}
		}
		depth++;//cout<<done<<endl;
	}
	return;
}

int tranint(char x)
{
	if (x == 'y') return 0;
	if (x == 'w') return 1;
	if (x == 'b') return 2;
	if (x == 'g') return 3;
	if (x == 'r') return 4;
	if (x == 'o') return 5;
}

int jiaokuai(int x, int y, int z)//角块的识别 
{
	int a, b, c;
	a = 0; b = 3; c = 4; 
	if ((x == a && y == b && z == c) || (x == a && z == b && y == c) || (y == a && x == b && z == c) || (y == a && z == b && x == c) || (z == a && x == b && y == c) || (z == a && y == b && x == c))
		return 0;
	a = 0; b = 2; c = 4; 
	if ((x == a && y == b && z == c) || (x == a && z == b && y == c) || (y == a && x == b && z == c) || (y == a && z == b && x == c) || (z == a && x == b && y == c) || (z == a && y == b && x == c)) 
		return 1;
	a = 0; b = 2; c = 5; 
	if ((x == a && y == b && z == c) || (x == a && z == b && y == c) || (y == a && x == b && z == c) || (y == a && z == b && x == c) || (z == a && x == b && y == c) || (z == a && y == b && x == c)) 
		return 2;
	a = 0; b = 3; c = 5; 
	if ((x == a && y == b && z == c) || (x == a && z == b && y == c) || (y == a && x == b && z == c) || (y == a && z == b && x == c) || (z == a && x == b && y == c) || (z == a && y == b && x == c))
		return 3;
	a = 1; b = 3; c = 4; 
	if ((x == a && y == b && z == c) || (x == a && z == b && y == c) || (y == a && x == b && z == c) || (y == a && z == b && x == c) || (z == a && x == b && y == c) || (z == a && y == b && x == c)) 
		return 4;
	a = 1; b = 2; c = 4; 
	if ((x == a && y == b && z == c) || (x == a && z == b && y == c) || (y == a && x == b && z == c) || (y == a && z == b && x == c) || (z == a && x == b && y == c) || (z == a && y == b && x == c)) 
		return 5;
	a = 1; b = 2; c = 5; 
	if ((x == a && y == b && z == c) || (x == a && z == b && y == c) || (y == a && x == b && z == c) || (y == a && z == b && x == c) || (z == a && x == b && y == c) || (z == a && y == b && x == c)) 
		return 6;
	a = 1; b = 3; c = 5; 
	if ((x == a && y == b && z == c) || (x == a && z == b && y == c) || (y == a && x == b && z == c) || (y == a && z == b && x == c) || (z == a && x == b && y == c) || (z == a && y == b && x == c))
		return 7;
}

int lengkuai(int x, int y)
{
	int a, b;
	a = 0; b = 3; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 0;
	a = 0; b = 4; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 1;
	a = 0; b = 2; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 2;
	a = 0; b = 5; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 3;
	a = 1; b = 3; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 4;
	a = 1; b = 4; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 5;
	a = 1; b = 2; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 6;
	a = 1; b = 5; 
	if ((x == a && y == b) || (x == b && y == a))
		return 7;
	a = 4; b = 3; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 8;
	a = 4; b = 2; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 9;
	a = 5; b = 2; 
	if ((x == a && y == b) || (x == b && y == a)) 
		return 10;
	a = 5; b = 3;
	if ((x == a && y == b) || (x == b && y == a)) 
		return 11;
}

int zhongji(int kuai, int wei, int c0, int c1)
{
	if (kuai == 0 && wei == 0)
	{
		if (c0 <= 1) return 0;
		if (c1 <= 1) return 1;
	}
	if (kuai == 0 && wei == 1)
	{
		if (c0 <= 1) return 1;
		if (c1 <= 1) return 0;
	}
	if (kuai == 1 && wei == 0)
	{
		if (c0 >= 2 && c0 <= 3) return 1;
		if (c1 >= 2 && c1 <= 3) return 0;
	}
	if (kuai == 1 && wei == 1)
	{
		if (c0 >= 2 && c0 <= 3) return 0;
		if (c1 >= 2 && c1 <= 3) return 1;
	}
}

Cube getcube1()//通过色相获取魔方初始状态
{
	Cube1 x; Cube y; 
	int tmp[10]; char amp[10];
	for (int i = 1; i <= 9; i++)//上面 
	{
		cin >> amp[i]; tmp[i] = tranint(amp[i]);
	}
	x.co1[2].color[0] = tmp[1];
	x.co1[3].color[0] = tmp[3];
	x.co1[1].color[0] = tmp[7];
	x.co1[0].color[0] = tmp[9];
	x.eo1[3].color[0] = tmp[2];
	x.eo1[2].color[0] = tmp[4];
	x.eo1[0].color[0] = tmp[6];
	x.eo1[1].color[0] = tmp[8];
	for (int i = 1; i <= 9; i++)//下面 
	{
		cin >> amp[i]; tmp[i] = tranint(amp[i]);
	}
	x.co1[5].color[0] = tmp[1];
	x.co1[4].color[0] = tmp[3];
	x.co1[6].color[0] = tmp[7];
	x.co1[7].color[0] = tmp[9];
	x.eo1[5].color[0] = tmp[2];
	x.eo1[6].color[0] = tmp[4];
	x.eo1[4].color[0] = tmp[6];
	x.eo1[7].color[0] = tmp[8];
	for (int i = 1; i <= 9; i++)//左面 
	{
		cin >> amp[i]; tmp[i] = tranint(amp[i]);
	}
	x.co1[2].color[1] = tmp[1];
	x.co1[1].color[2] = tmp[3];
	x.co1[6].color[2] = tmp[7];
	x.co1[5].color[1] = tmp[9];
	x.eo1[2].color[1] = tmp[2];
	x.eo1[10].color[0] = tmp[4];
	x.eo1[9].color[0] = tmp[6];
	x.eo1[6].color[1] = tmp[8];
	for (int i = 1; i <= 9; i++)//右面 
	{
		cin >> amp[i]; tmp[i] = tranint(amp[i]);
	}
	x.co1[0].color[1] = tmp[1];
	x.co1[3].color[2] = tmp[3];
	x.co1[4].color[2] = tmp[7];
	x.co1[7].color[1] = tmp[9];
	x.eo1[0].color[1] = tmp[2];
	x.eo1[8].color[0] = tmp[4];
	x.eo1[11].color[0] = tmp[6];
	x.eo1[4].color[1] = tmp[8];
	for (int i = 1; i <= 9; i++)//前面 
	{
		cin >> amp[i]; tmp[i] = tranint(amp[i]);
	}
	x.co1[1].color[1] = tmp[1];
	x.co1[0].color[2] = tmp[3];
	x.co1[5].color[2] = tmp[7];
	x.co1[4].color[1] = tmp[9];
	x.eo1[1].color[1] = tmp[2];
	x.eo1[9].color[1] = tmp[4];
	x.eo1[8].color[1] = tmp[6];
	x.eo1[5].color[1] = tmp[8];
	for (int i = 1; i <= 9; i++)//后面 
	{
		cin >> amp[i]; tmp[i] = tranint(amp[i]);
	}
	x.co1[3].color[1] = tmp[1];
	x.co1[2].color[2] = tmp[3];
	x.co1[7].color[2] = tmp[7];
	x.co1[6].color[1] = tmp[9];
	x.eo1[3].color[1] = tmp[2];
	x.eo1[11].color[1] = tmp[4];
	x.eo1[10].color[1] = tmp[6];
	x.eo1[7].color[1] = tmp[8];
	for (int i = 0; i <= 7; i++)
	{
		y.co[i].c = Corner(jiaokuai(x.co1[i].color[0], x.co1[i].color[1], x.co1[i].color[2]));
		for (int j = 0; j <= 2; j++)
		{
			if (x.co1[i].color[j] <= 1)
			{
				y.co[i].o = j;
				break;
			}
		}
	}
	for (int i = 0; i <= 11; i++)
	{
		y.eo[i].e = Edge(lengkuai(x.eo1[i].color[0], x.eo1[i].color[1]));
		y.eo[i].o = zhongji(y.eo[i].e / 8, i / 8, x.eo1[i].color[0], x.eo1[i].color[1]);
	}
	return y;
}

Cube getcube2()//通过打乱公式获取魔方初始状态 
{
	Cube ans;
	for (int i = 0; i <= 7; i++)
	{
		ans.co[i].c = Corner(i); ans.co[i].o = 0;
	}
	for (int i = 0; i <= 11; i++)
	{
		ans.eo[i].e = Edge(i); ans.eo[i].o = 0;
	}
	string a;
	getline(cin, a); 
	getline(cin, a);
	a = a + " ";
	int len = a.length();
	int hou = -1, qian = 0;
	for (int i = 0; i <= len - 1; i++)
	{
		if (a.at(i) == ' ')
		{
			qian = i;
			int len = qian - hou - 1;
			string x = a.substr(hou + 1, len);
			hou = qian;
			int ci = 0;
			if (x.length() == 1) 
				ci = 1;
			else if (x.substr(1) == "'") 
				ci = 3;
			else if (x.at(1) == '2') 
				ci = 2;
			int lei = 0;
			char tmp = x.at(0);
			switch (tmp)
			{
			case 'U':lei = 0; 
				break;
			case 'D':lei = 1; 
				break;//U1 U1 D1 D D L1
			case 'L':lei = 2; 
				break;
			case 'R':lei = 3; 
				break;
			case 'F':lei = 4;
				break;
			case 'B':lei = 5; 
				break;
			}
			for (int i = 1; i <= ci; i++)
				ans = cubeMove(ans, lei);
		}
	}
	return ans;
}

struct zhuan
{
	int xulie[10000000];
	int len = 0;
}ans;

int flag = 0; 
int xu = 0; 
int minn = 25;

string trans[18] = { "U","U2","U'","D","D2","D'","L","L2","L'",
				  "R","R2","R'","F","F2","F'","B","B2","B'" };

int initccp, initcep1, initcep2;
int pan[10000];

void search2(int CP, int EP1, int EP2, int cnt, int togo2)//阶段二的搜索 
{
	if (flag)
		return;
	if (togo2 == 0)
	{
		if (CP == 0 && EP1 == 0 && EP2 == 0)
		{
			xu++; 
			cout << xu << ":" << ans.len << " ";
			for (int i = 1; i <= ans.len; i++)
				cout << trans[ans.xulie[i]] << " ";
			cout << endl; 
			minn = ans.len;
			flag = 1;
			pan[cnt]--;
		}
		return;
	}
	else
	{
		int cp, ep1, ep2;
		for (int i = 0; i <= 9; i++)
		{
			if (flag) 
				return;
			int x = cz[i].a;
			int y = cz[i].b;
			int j = 3 * x + y;
			int m = ans.xulie[ans.len];
			if (m / 3 == x) 
				continue;
			if (m / 3 - x == 1 && (m / 3) % 2 == 1)
				continue;
			cp = cpMoveTable[CP][j];
			ep1 = epMoveTable1[EP1][j];
			ep2 = epMoveTable2[EP2][j];
			int dist2 = max(max(PruneTable4[cp], PruneTable5[ep1]), PruneTable6[ep2]);
			if (dist2 > togo2 - 1) 
				continue;
			ans.len++;
			ans.xulie[ans.len] = x * 3 + y;
			search2(cp, ep1, ep2, cnt, togo2 - 1);
			ans.len--;
		}
	}
	return;
}

void search1(int twist, int flip, int slice, int togo1)//阶段一的搜索 
{
	if (togo1 == 0)
	{
		if (twist == 0 && flip == 0 && slice == 0)
		{
			int x = initccp; 
			Cube a = initc, b;
			for (int i = 1; i <= ans.len; i++)
			{
				x = cpMoveTable[x][ans.xulie[i]];
				for (int j = 0; j <= ans.xulie[i] % 3; j++)
				{
					edgeMultiply1(&a, &Move[ans.xulie[i] / 3], &b); a = b;
				}
			}
			int y = idedgep(b), z = idedgez(b);
			//cout<<x<<" "<<y<<" "<<z<<endl;
			int m = max(max(PruneTable4[x], PruneTable5[y]), PruneTable6[z]);
			for (int i = m; i <= minn - ans.len; i++)
			{
				if (flag) 
					break;
				if (pan[i + ans.len] <= 0) 
					continue;
				search2(x, y, z, i + ans.len, i);
			}
			flag = 0;
		}
		return;
	}
	else
	{
		int flip1, twist1, slice1;
		for (int i = 0; i <= 17; i++)
		{
			int x = ans.xulie[ans.len];
			if (x / 3 == i / 3) 
				continue;
			if (x / 3 - i / 3 == 1 && (x / 3) % 2 == 1) 
				continue;
			twist1 = twistMoveTable[twist][i];
			flip1 = flipMoveTable[flip][i];
			slice1 = sliceMoveTable[slice][i];
			int dist1 = max(max(PruneTable1[twist1], PruneTable2[flip1]), PruneTable3[slice1]);
			if (dist1 > togo1 - 1)
				continue;
			ans.len++;
			ans.xulie[ans.len] = i;
			search1(twist1, flip1, slice1, togo1 - 1);
			ans.len--;
		}
	}
	return;
}

typedef enum { g, w, o, r, y, b } color;

int main()
{
	//{URF,UFL,ULB,UBR,DFR,DLF,DBL,DRB}
	//{UR,UF,UL,UB,DR,DF,DL,DB,FR,FL,BL,BR} 
	Move[U] = { //URF槽的元素被UFL槽的元素替代,且顺时针扭转,方向加1
	{{UBR,0},{URF,0},{UFL,0},{ULB,0},{DFR,0},{DLF,0},{DBL,0},{DRB,0}},
	  {{UB,0},{UR,0},{UF,0},{UL,0},{DR,0},{DF,0},{DL,0},{DB,0},{FR,0},{FL,0},{BL,0},{BR,0}}
	};
	Move[D] = { //URF槽的元素被UFL槽的元素替代,且顺时针扭转,方向加1
	{{URF,0},{UFL,0},{ULB,0},{UBR,0},{DLF,0},{DBL,0},{DRB,0},{DFR,0}},
	  {{UR,0},{UF,0},{UL,0},{UB,0},{DF,0},{DL,0},{DB,0},{DR,0},{FR,0},{FL,0},{BL,0},{BR,0}}
	};
	Move[L] = { //URF槽的元素被UFL槽的元素替代,且顺时针扭转,方向加1
	{{URF,0},{ULB,1},{DBL,2},{UBR,0},{DFR,0},{UFL,2},{DLF,1},{DRB,0}},
	  {{UR,0},{UF,0},{BL,0},{UB,0},{DR,0},{DF,0},{FL,0},{DB,0},{FR,0},{UL,0},{DL,0},{BR,0}}
	};
	Move[R] = { //URF槽的元素被UFL槽的元素替代,且顺时针扭转,方向加1
	{{DFR,2},{UFL,0},{ULB,0},{URF,1},{DRB,1},{DLF,0},{DBL,0},{UBR,2}},
	  {{FR,0},{UF,0},{UL,0},{UB,0},{BR,0},{DF,0},{DL,0},{DB,0},{DR,0},{FL,0},{BL,0},{UR,0}}
	};
	Move[F] = { //URF槽的元素被UFL槽的元素替代,且顺时针扭转,方向加1
	{{UFL,1},{DLF,2},{ULB,0},{UBR,0},{URF,2},{DFR,1},{DBL,0},{DRB,0}},
		{{UR,0},{FL,1},{UL,0},{UB,0},{DR,0},{FR,1},{DL,0},{DB,0},{UF,1},{DF,1},{BL,0},{BR,0}}
	};
	Move[B] = { //URF槽的元素被UFL槽的元素替代,且顺时针扭转,方向加1
	{{URF,0},{UFL,0},{UBR,1},{DRB,2},{DFR,0},{DLF,0},{ULB,2},{DBL,1}},
	  {{UR,0},{UF,0},{UL,0},{BR,1},{DR,0},{DF,0},{DL,0},{BL,1},{FR,0},{FL,0},{UB,1},{DB,1}}
	};
	initTwistMoveTable();
	initPruneTable1();
	initFlipMoveTable();
	initPruneTable2();
	initSliceMoveTable();
	initPruneTable3();
	initcpMoveTable();
	initepMoveTable1();
	initepMoveTable2();
	initPruneTable4();
	initPruneTable5();
	initPruneTable6();
	for (int i = 0; i <= 999; i++) 
		pan[i] = 3;
	int n;
	cout << "欢迎来到简化版kociemba algorithm解魔方程序" << endl;
	cout << "请选择表述魔方的初始状态的方式" << endl;
	cout << "方式一:输入魔方六个面的颜色" << endl;
	cout << "方式二:输入标准打乱公式" << endl;
	cout << "选择方式一请输入 1,选择方式二请输入 2" << endl;
	cin >> n;
	if (n == 1)
	{
		cout << "请输入魔方六个面的色块颜色,标准魔方配色(黄,白,蓝,绿,红,橙)分别用 y,w,b,g,r,o 表示" << endl;
		cout << "请输入以空格隔开的54个色块颜色对应的字母,以黄色面为顶面,红色面为前面" << endl;
		cout << "请按上,下,左,右,前,后面的顺序输入,每个面的颜色均以左上角开始,从左到右,从上到下" << endl;
		cout << "关于左上角色块的确定,请固定前面和上面,上面的左上角远离前面,四个侧面的左上角块与上面相邻,下面的左上角块与前面相邻" << endl;
		initc = getcube1();
		ans.xulie[0] = 7890;
		cout << "开始求解" << endl;
		int twist = idcornero(initc);
		int flip = idedgeo(initc);
		int slice = idslice(initc);
		initccp = idcornerp(initc);
		initcep1 = idedgep(initc);
		initcep2 = idedgez(initc);
		int x = max(max(PruneTable1[twist], PruneTable2[flip]), PruneTable3[slice]);
		for (int i = x; i <= minn; i++)
		{
			search1(twist, flip, slice, i);
		}
	}
	if (n == 2)
	{
		cout << "请将所有打乱公式输入到一行,示例 U(顶层顺时针),U'(右上角的'为英文的)(顶层逆时针),U2(顶层180°)UDLRFB" << endl;
		initc = getcube2();
		ans.xulie[0] = 7890;
		cout << "开始求解" << endl;
		int twist = idcornero(initc);
		int flip = idedgeo(initc);
		int slice = idslice(initc);
		initccp = idcornerp(initc);
		initcep1 = idedgep(initc);
		initcep2 = idedgez(initc);
		int x = max(max(PruneTable1[twist], PruneTable2[flip]), PruneTable3[slice]);
		for (int i = x; i <= minn; i++)
		{
			search1(twist, flip, slice, i);
		}
	}
	return 0;
}

//作者:子任 - 逸仙 https ://www.bilibili.com/read/cv20359840 出处:bilibili

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值