魔方模拟器_对魔方一直重复同一组操作,是否一定能复原

本文探讨了如何通过循环群的概念解释魔方复原问题。作者从一个数列操作的角度出发,证明了通过重复一组特定操作,数列可以在一定次数后恢复原状,并给出了通用解决方案。此外,文章还介绍了利用C++程序和魔方模拟器进行实验验证,并展示了如何将这一理论应用于魔方问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

7c0b51e46d7fb7c9681adce74eca814f.png
本文使用 Zhihu On VSCode 创作并发布

写完文章后才发现这属于循环群,那本文就当作是循环群的通俗解释吧.


这是那天我和同学推出来的结论:

对任意封闭体系内的元素进行互换位置的操作,
一定能在有限次操作后恢复到操作前的状态,
且这有限次操作的次数是可以计算的.

下面尝试给出其证明,若有误欢迎指出.


本文 异步(划掉) 发布于我的博客,略有更改.

或许更好的阅读体验:

由魔方问题引出的思考 | Xecades 的博客​blog.xecades.xyz

由来

在上一篇博文中,我提及:“和同学讨论有关魔方还原的问题”,同学(ZLR)的原话大概是这样的:

既然一直重复 “上左” 操作需要一百多次就能复原,“上右” 需要六十多次也能复原. 那对魔方一直重复同一组操作,是否也一定能复原呢?

之后,同学给出了他的证明方案(文末介绍),我个人认为他是正确的,并将此方法推广到其他情况.

下面换另一个角度介绍我的方法.


新问题

我有一串数列 A,标号 1 ~ 10:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

我规定一次操作为:将该数列的元素按照一定的顺序 B 互换位置.

那么问至少经过多少次操作能使数列恢复原样(复原).

例如,我规定顺序 B 为:

  1. 先将第 1 个位置的数放到第 8 个位置;
  2. 然后将第 2 个位置的数放到第 10 个位置;
  3. 然后将第 3 个位置的数放到第 5 个位置;
  4. 然后将第 4 个位置的数放到第 3 个位置;
  5. 然后将第 5 个位置的数放到第 7 个位置;
  6. 然后将第 6 个位置的数放到第 9 个位置;
  7. 然后将第 7 个位置的数放到第 6 个位置;
  8. 然后将第 8 个位置的数放到第 1 个位置;
  9. 然后将第 9 个位置的数放到第 2 个位置;
  10. 最后将第 10 个位置的数放到第 4 个位置.

为了方便,我们用序列 8, 10, 5, 3, 7, 9, 6, 1, 2, 4 来表示一次操作.

一直按照该操作进行,我们得到以下数列:

<1 次操作> 8 9 4 10 3 7 5 1 6 2
<2 次操作> 1 6 10 2 4 5 3 8 7 9
<3 次操作> 8 7 2 9 10 3 4 1 5 6
<4 次操作> 1 5 9 6 2 4 10 8 3 7
<5 次操作> 8 3 6 7 9 10 2 1 4 5
<6 次操作> 1 4 7 5 6 2 9 8 10 3
<7 次操作> 8 10 5 3 7 9 6 1 2 4
<8 次操作> 1 2 3 4 5 6 7 8 9 10

可见,数列 A 在 8 次 B 操作后复原.


解释

仍按照先前的例子,B = 8, 10, 5, 3, 7, 9, 6, 1, 2, 4,共需 8 次复原.

前面我们提到,顺序 B 为:

  1. 先将第 1 个位置的数放到第 8 个位置;
  2. 然后将第 2 个位置的数放到第 10 个位置;
  3. 然后将第 3 个位置的数放到第 5 个位置;
  4. 然后将第 4 个位置的数放到第 3 个位置;
  5. 然后将第 5 个位置的数放到第 7 个位置;
  6. 然后将第 6 个位置的数放到第 9 个位置;
  7. 然后将第 7 个位置的数放到第 6 个位置;
  8. 然后将第 8 个位置的数放到第 1 个位置;
  9. 然后将第 9 个位置的数放到第 2 个位置;
  10. 最后将第 10 个位置的数放到第 4 个位置.

它又可以表示为:

1 -> 8
2 -> 10
3 -> 5
4 -> 3
5 -> 7
6 -> 9
7 -> 6
8 -> 1
9 -> 2
10 -> 4

如果把这些数据点连成一个图,效果如下:

8514531466fa6662e4226f5c0dbe23a0.png
图片采用 Csacademy 绘制

显然,这些数据一定会连成一个或多个环,因为这是互换位置的操作,每个数据节点一定有且只有一个输入和一个输出.

这样便涉及到了我熟悉的图论领域了. 也就是说,最终绘制出的图形一定是多个有向环的集合,每进行一次操作,每个环上的点就会按照箭头所指的方向 “前进” 一格.

对于每一个环,“前进” 一圈就能回到原位,如果要让所有的环回到原位(复原),只需操作每个环长度的最小公倍数次就好了.

因此,在这个例子中,只需要操作 2 和 8 的最小公倍数 8 次就能复原.


扩展

因此,我们可以给出这种问题的通解:列出变换的点;画出对应的图;数每个环的长度,求最小公倍数即为结果.

我们拿一个稍微复杂点的例子:

B = 2, 6, 5, 7, 3, 1, 8, 10, 4, 9

该数据共需要 30 次操作才能复原.

它的变化情况是这样的:

1 -> 2
2 -> 6
3 -> 5
4 -> 7
5 -> 3
6 -> 1
7 -> 8
8 -> 10
9 -> 4
10 -> 9

绘制出有向图:

18115bc9d0fa7bf1753c44433d86467a.png
图片采用 Csacademy 绘制

其中存在三个环,长度分别为:2, 5, 3,最小公倍数恰恰为 30.

为了方便测试,我写了一个简单的 C++ 程序来随机生成 B 并操作数列 A:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <ctime>
using namespace std;

#define MAXN 10000

int n = 10;
int A[MAXN];
int B[MAXN];

bool check();
void apply();

int main()
{
	for (int i = 1; i <= n; i++)
		A[i] = B[i] = i;
	srand(time(0));
	random_shuffle(B + 1, B + n + 1);

	cout << "B = ";
	for (int i = 1; i <= n; i++)
		cout << B[i] << " ";
	cout << endl << endl;

	for (int i = 1; i <= n; i++)
		cout << i << " " << B[i] << endl;
	cout << endl << endl;

	for (int test = 1;; test++)
	{
		apply();
		cout << "<" << test << "> ";
		for (int i = 1; i <= n; i++)
			cout << A[i] << " ";
		cout << endl;
		if (check())
			getchar();
	}
	return 0;
}

void apply()
{
	int tA[MAXN] = {0};
	for (int i = 1; i <= n; i++)
		tA[B[i]] = A[i];
	for (int i = 1; i <= n; i++)
		A[i] = tA[i];
}

bool check()
{
	for (int i = 1; i <= n; i++)
		if (A[i] != i)
			return false;
	return true;
}

魔方

前面提出的模型是可以广泛应用的,其中一个例子便是之前提出的魔方问题.

下面使用我自己开发的魔方模拟器进行研究,它的介绍在这里:

用于学术研究的魔方模拟器​blog.xecades.xyz

以操作 “左上” 为例,也就是指令 RU.

我们把魔方的每一个格子依次编号为 1 ~ 54:

9bd929da22d97e4641a3b71e98fe69f9.png

进行一次 RU 操作:

aadbf66ff3600d27586ebc372e958fe4.png

统计变化的块:

2a358f30c7a7827dadab35a063fb9540.png

输出如下:

3 1
6 2
27 3
2 4
26 6
1 7
4 8
25 9
19 10
22 13
43 16
30 19
29 22
28 25
44 26
45 27
9 28
33 29
36 30
51 31
35 33
48 34
31 35
34 36
52 43
53 44
54 45
16 48
13 51
7 52
8 53
10 54

输入到图论绘图工具 csacademy 中,稍作整理,我们得到图:

bbb7ac0ef8b629242ff653e84d9f2fd2.png
图片采用 Csacademy 绘制

在这个例子中,出现了四个环,其长度分别为:

3, 7, 7, 15

其最小公倍数为 105,表示一直进行操作 “上左” 至少需要 105 次才能复原.

我们可以通过 Cube Simulator 验证:

db041090aa8b5ce5dd62c6027a038b58.png

可见次结论是正确的.

另外,计算一个图中环的个数,信息学领域可以很轻松地用 bfs 算法(广度优先搜索)实现,这里我就不给出代码了.


另:强烈推荐 图论绘图工具 csacademy.

若有逻辑上的漏洞,欢迎在评论区指出.
作者才疏学浅,有误望海纳.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值