puzzle(0334)双面数局

一,双面数局

最强大脑 同款项目

二,计算机求解

1,交换公式

参考交换公式自动推导V6

2,通用操作

cpp 复制代码
vector<Opt> getOpts(int n)
{
	vector<int>v0;
	for (int i = 0; i < n*n * 2; i++)v0.push_back(i);
	vector<Opt>ans;
	for (int i = 0; i < n; i++) {
		string optName = "第";
		optName += std::to_string(i + 1);
		optName += "行往右";
		vector<int>v = v0;
		int s1 = i * n, s2 = i * n + n * n;
		vector<int>nums;
		for (int i = s1; i < s1 + n; i++)nums.push_back(i);
		for (int i = s2; i < s2 + n; i++)nums.push_back(i);
		for (int i = 0; i < nums.size(); i++)v[nums[(i + 1) % nums.size()]] = nums[i];
		Opt opt{ { v } ,optName };
		ans.push_back(opt);
	}
	for (int i = 0; i < n; i++) {
		string optName = "第";
		optName += std::to_string(i + 1);
		optName += "列往下";
		vector<int>v = v0;
		int s1 = i, s2 = n * n * 2 - i - 1;
		vector<int>nums;
		for (int i = s1; i < s1 + n * n; i += n)nums.push_back(i);
		for (int i = s2; i > s2 - n * n; i -= n)nums.push_back(i);
		for (int i = 0; i < nums.size(); i++)v[nums[(i + 1) % nums.size()]] = nums[i];
		Opt opt{ { v } ,optName };
		ans.push_back(opt);
	}
	return ans;
}

3,n=2

cpp 复制代码
int main()
{
	int n = 2;
	CubeBlock block1(0, n * n * 2);
	vector<CubeBlock>b = vector<CubeBlock>{ block1 };
	vector<Opt> v = getOpts(n);
	CubeOpt op1(b, v[0]);
	CubeOpt op2(b, v[1]);
	CubeOpt op3(b, v[2]);
	CubeOpt op4(b, v[3]);
	vector<CubeOpt>opts = { op1,op2,op3,op4 };
	for (int i = 0; i < opts.size(); i++)mans[i] = opts[i].getName();
	Cube cube(b, opts);
	cube.bfs(0, 2, 2);
	return 0;
}

输出:

2,1,0,3,4,5,6,7,

0第1行往右 0第1行往右 1第2行往右 2第1列往下 0第1行往右 1第2行往右 2第1列往下 1第2行往右 2第1列往下 0第1行往右 3第2列往下

这是交换0和2的公式

4,n=3

cpp 复制代码
int main()
{
	int n = 3;
	CubeBlock block1(0, n * n * 2);
	vector<CubeBlock>b = vector<CubeBlock>{ block1 };
	vector<Opt> v = getOpts(n);
	CubeOpt op1(b, v[0]);
	CubeOpt op2(b, v[1]);
	CubeOpt op3(b, v[2]);
	CubeOpt op4(b, v[3]);
	CubeOpt op5(b, v[4]);
	CubeOpt op6(b, v[5]);
	vector<CubeOpt>opts = { op1,op2,op3,op4,op5,op6 };
	for (int i = 0; i < opts.size(); i++)mans[i] = opts[i].getName();
	Cube cube(b, opts);
	cube.bfs(0, 2, 2);
	return 0;
}

输出:

0,1,7,3,4,5,6,2,8,9,10,11,12,13,14,15,16,17,

0第1行往右 0第1行往右 4第2列往下 1第2行往右 1第2行往右 1第2行往右 4第2列往下 4第2列往下 0第1行往右 0第1行往右 0第1行往右 0第1行往右 0第1行往右 1第2行往右 1第2行往右 0第1行往右 0第1行往右 0第1行往右 0第1行往右 0第1行往右 1第2行往右

这是交换2和7的公式

化简结果:

第1行往右 *2

第2列往下

第2行往右*3

第2列往下*2

第1行往左*2

第2行往右*3

5,n=4

代码1:略

运行结果:得到0 18 19 23交换的公式(不是1个4阶置换,而是2个2阶置换)

代码2:

cpp 复制代码
int main()
{
	int n = 4;
	CubeBlock block1(0, n * n * 2);
	vector<CubeBlock>b = vector<CubeBlock>{ block1 };
	vector<Opt> v = getOpts(n);
	CubeOpt op1(b, v[0]);
	CubeOpt op2(b, v[1]);
	CubeOpt op3(b, v[2]);
	CubeOpt op4(b, v[3]);
	CubeOpt op5(b, v[4]);
	CubeOpt op6(b, v[5]);
	CubeOpt op7(b, v[6]);
	CubeOpt op8(b, v[7]);
	Opt opt9{ { {19,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,23,0,20,21,22,18,24,25,26,27,28,29,30,31} } ,"【1下1右1上1左】" };
	CubeOpt op9(b, opt9);
	vector<CubeOpt>opts = { op1,op2,op3,op4,op5,op6,op7,op8,op9 };
	for (int i = 0; i < opts.size(); i++)mans[i] = opts[i].getName();
	Cube cube(b, opts);
	cube.bfs(0, 2, 3);
	return 0;
}

输出:

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,21,19,20,22,18,23,24,25,26,27,28,29,30,31,

1第2行往右 6【1下1右1上1左】 1第2行往右 6【1下1右1上1左】 1第2行往右 1第2行往右 1第2行往右 1第2行往右 1第2行往右 1第2行往右

这是18-22-21三者轮换(顺时针旋转)的公式

化简结果:

第2行往右

【1下1右1上1左】

第2行往右

【1下1右1上1左】

第2行往左*2

我们把这个公式记作三轮换公式

代码3:

cpp 复制代码
int main()
{
	int n = 4;
	CubeBlock block1(0, n * n * 2);
	vector<CubeBlock>b = vector<CubeBlock>{ block1 };
	vector<Opt> v = getOpts(n);
	CubeOpt op1(b, v[0]);
	CubeOpt op2(b, v[1]);
	CubeOpt op3(b, v[2]);
	CubeOpt op4(b, v[3]);
	CubeOpt op5(b, v[4]);
	CubeOpt op6(b, v[5]);
	CubeOpt op7(b, v[6]);
	CubeOpt op8(b, v[7]);
	Opt opt9{ { {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,21,19,20,22,18,23,24,25,26,27,28,29,30,31} } ,"三轮换" };
	CubeOpt op9(b, opt9);
	vector<CubeOpt>opts = { op2,op9 };
	for (int i = 0; i < opts.size(); i++)mans[i] = opts[i].getName();
	Cube cube(b, opts);
	cube.bfs(0, 2, 2);
	return 0;
}

输出:

0,1,2,3,4,6,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,

0第2行往右 1三轮换 0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 1三轮换 0第2行往右

这是交换5和6的公式

化简结果:

第2行往右

【2右1下1右1上1左】 *4

第2行往右

【2右1下1右1上1左】 *4

第2行往左

其中,2右就是第2行往右,以此类推。

同理,还有交换4和7的公式

第2行往右*3

【1下1右1上1左】

第2行往右

【1下1右1上1左】

第2行往右 *2

【1下1右1上1左】

第2行往右

【1下1右1上1左】

第2行往左*2

【1下1右1上1左】

第2行往右

【1下1右1上1左】

第2行往右 *2

【1下1右1上1左】

第2行往右

【1下1右1上1左】

第2行往右

【1下1右1上1左】

第2行往右

【1下1右1上1左】

第2行往左*2

三,高阶场景

前面的校验,基本上已经形成固定的模式了,只需要数字改一改就能得到高阶的公式了。

和魔方不同的是,魔方是公式本身进行微调即可得到新公式,而双面数局是产生n=k的公式的代码微调即可得到产生n=k+1的公式的代码,但n=k的公式和n=k+1的公式之间差别还是挺大的。

1,通用操作

我们把"1下1右1上1左"这个小公式进行参数化,避免手动输入置换表

cpp 复制代码
vector<Opt> getOpts(int n)
{
	vector<int>v0;
	for (int i = 0; i < n*n * 2; i++)v0.push_back(i);
	vector<Opt>ans;
	for (int i = 0; i < n; i++) {
		string optName = "第";
		optName += std::to_string(i + 1);
		optName += "行往右";
		vector<int>v = v0;
		int s1 = i * n, s2 = i * n + n * n;
		vector<int>nums;
		for (int i = s1; i < s1 + n; i++)nums.push_back(i);
		for (int i = s2; i < s2 + n; i++)nums.push_back(i);
		for (int i = 0; i < nums.size(); i++)v[nums[(i + 1) % nums.size()]] = nums[i];
		Opt opt{ { v } ,optName };
		ans.push_back(opt);
	}
	for (int i = 0; i < n; i++) {
		string optName = "第";
		optName += std::to_string(i + 1);
		optName += "列往下";
		vector<int>v = v0;
		int s1 = i, s2 = n * n * 2 - i - 1;
		vector<int>nums;
		for (int i = s1; i < s1 + n * n; i += n)nums.push_back(i);
		for (int i = s2; i > s2 - n * n; i -= n)nums.push_back(i);
		for (int i = 0; i < nums.size(); i++)v[nums[(i + 1) % nums.size()]] = nums[i];
		Opt opt{ { v } ,optName };
		ans.push_back(opt);
	}
	string optName = "1下1右1上1左";
	vector<int>v = v0;
	v[0] = n * n + n - 1, v[n * n + n - 1] = 0;
	v[n * n + n - 2] = n * n + n * 2 - 1, v[n * n + n * 2 - 1] = n * n + n - 2;
	Opt opt{ { v } ,optName };
	ans.push_back(opt);
	return ans;
}

2,n=5

代码1:

cpp 复制代码
int main()
{
	int n = 5;
	CubeBlock block1(0, n * n * 2);
	vector<CubeBlock>b = vector<CubeBlock>{ block1 };
	vector<Opt> v = getOpts(n);
	CubeOpt op1(b, v[0]);
	CubeOpt op2(b, v[1]);
	CubeOpt op3(b, v[2]);
	CubeOpt op4(b, v[3]);
	CubeOpt op5(b, v[4]);
	CubeOpt op6(b, v[5]);
	CubeOpt op7(b, v[6]);
	CubeOpt op8(b, v[7]);
	CubeOpt op9(b, v[8]);
	CubeOpt op10(b, v[9]);
	CubeOpt op11(b, v[10]);
	vector<CubeOpt>opts = { op1,op2,op11 };
	for (int i = 0; i < opts.size(); i++)mans[i] = opts[i].getName();
	Cube cube(b, opts);
	cube.bfs(0, 2, 3);
	return 0;
}

输出:

0,1,2,3,4,28,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,34,29,30,31,32,33,5,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,

1第2行往右 1第2行往右 1第2行往右 1第2行往右 1第2行往右 1第2行往右 1第2行往右 1第2行往右 1第2行往右 21下1右1上1左 1第2行往右 21下1右1上1左

这是一个三轮换的公式。

化简结果:

第2行往左

【1下1右1上1左】

第2行往右

【1下1右1上1左】

代码2:

cpp 复制代码
int main()
{
	int n = 5;
	CubeBlock block1(0, n * n * 2);
	vector<CubeBlock>b = vector<CubeBlock>{ block1 };
	vector<Opt> v = getOpts(n);
	CubeOpt op1(b, v[0]);
	CubeOpt op2(b, v[1]);
	CubeOpt op3(b, v[2]);
	CubeOpt op4(b, v[3]);
	CubeOpt op5(b, v[4]);
	CubeOpt op6(b, v[5]);
	CubeOpt op7(b, v[6]);
	CubeOpt op8(b, v[7]);
	CubeOpt op9(b, v[8]);
	CubeOpt op10(b, v[9]);
	CubeOpt op11(b, v[10]);
	Opt opt{ { {0,1,2,3,4,28,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,34,29,30,31,32,33,5,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49} } ,"三轮换" };
	CubeOpt op12(b, opt);
	vector<CubeOpt>opts = { op2,op12 };
	for (int i = 0; i < opts.size(); i++)mans[i] = opts[i].getName();
	Cube cube(b, opts);
	cube.bfs(0, 2, 2);
	return 0;
}

输出1:

0,1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,

0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 1三轮换

这是交换7和8的公式

化简结果:

【2右1下1右1上1左】 *6

第2行往右

【2右1下1右1上1左】 *4

输出2:

0,1,2,3,4,5,6,9,8,7,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,

0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 1三轮换 0第2行往右 1三轮换 1三轮换 0第2行往右 0第2行往右 1三轮换 0第2行往右 0第2行往右 1三轮换

这是交换7和9的公式

化简结果:

【2右1下1右1上1左】 *6

第2行往左

【2右1下1右1上1左】 *2

第2行往左*2

【2右1下1右1上1左】 *6

相关推荐
And_Ii2 小时前
3740. 三个相等元素之间的最小距离 I
c++·算法
强盛机器学习~2 小时前
2026年SCI一区新算法-贝塞尔曲线优化算法(BCO)-公式原理详解与性能测评 Matlab代码免费获取
算法·matlab·进化计算·智能优化算法·元启发式算法·群体智能算法
翟天保Steven2 小时前
空间载波移相干涉算法(SPSI)
算法·激光干涉·精密量测
xin_nai2 小时前
判断质数(Java版)
算法
W23035765732 小时前
经典算法详解:最大子数组和(暴力 / 分治 / 动态规划 / 线段树)
算法·动态规划·最大字段和
呼啦啦5612 小时前
leetcode练习——栈和队列
算法·leetcode·职场和发展
yugi9878382 小时前
基于最大信息熵的粒子群优化算法图像分割(MATLAB实现)
开发语言·算法·matlab
计算机安禾3 小时前
【数据结构与算法】第40篇:图论(四):最短路径——Dijkstra算法与Floyd算法
c语言·数据结构·算法·排序算法·哈希算法·图论·visual studio
SccTsAxR3 小时前
算法进阶:贪心策略证明全攻略与二进制倍增思想深度解析
c++·经验分享·笔记·算法