来晚惹……@Lunatic 和 @KuriyamaMirai 都给出了很棒的证明。
那么,就由我来给出“简单”和“更强”的做法吧!
首先,如果你把所有开关都按一遍(由于每次会连带旁边两个,实际上按了三下),那么所有灯的状态都会反转。记作操作A。
然后,如果只按2号(连带13)和5号(连带46),那么除7号之外的灯的状态都会反转。记作操作B。
因此,只要把某盏灯记作7号,再执行操作A和B,就可以只改变该灯状态而不影响其他灯了。对所有“关”的灯来一遍,灯就全“开”了。完毕。
很简单有木有!
好,强结论来了:对于n盏灯,每次切换连续的m盏。(n,m)满足何种条件时,可以经过有限次操作获得所有状态呢?
请思考五秒:
五……
四……
三……
二……
一……
当当当!答案揭晓!
只要n与m互质且m为奇数就可以啦!
这还是一个充要条件哦!
下面开始证明:
首先,我们注意到“能通过有限次操作到达任意状态”等价于“能通过有限次操作改变其中一盏灯的状态而使其他盏灯状态不变”。这个很显然所以用不着证了吧……
——于是m与n就非互质不可了。否则你可以把所有灯按照序号除以r所得余数(r为n与m的大于1的公约数)分为r组,那么无论如何操作,任意两组之间“亮着的灯数的奇偶性”将保持相同或不同,而不会发生相同→不同或不同→相同的改变,自然也就无法做到“只改变一盏灯,不影响其他盏”了。
m也必须是奇数才行,否则“亮着的灯数”的奇偶性也无法改变……
反过来,如果n与m互质且m为奇数,是否必定存在一种方法可以做到“只改变一盏灯”呢?
其实很简单:连续按就行了。比如对于(47,15),你就第一次按1到15,第二次按16到30,然后是31到45,46到13(绕一圈了!),14到28,29到43……
根据裴蜀定理,n与m互质时,mx+by=1有整数解。用人话说就是:这么按下去,迟早有一次会按成“34到1”。
这意味着你已经按了k圈灯加一个灯。结果分两种:
一:其他灯都被按了偶数次,只有1号被按了奇数次,即整个过程中只有1号状态变了,成立!
二:与上边那个相反,只有1号保持不变,其他都反转了……不过没关系!因为m为奇数,所以只要把全部灯按一遍(由于连带,每盏灯被按了m次),就可以把所有灯都反转了。
至此,本题完结!
啦啦啦……
答主本人目前在被窝里,手机打字,莫名其妙就得出答案了。还是挺高兴滴!
所以,可以请你给我一个赞么?蟹蟹~
受 @Lunatic 启发,给出推广结论:
对于n盏灯,每次切换连续的m盏,且每盏灯具有k个状态。则能通过有限次操作得到所有状态的充要条件是:m与n互质且m与k互质。
必要性:对每盏灯,取状态值(0,1,2,…,k-1)。若(m,k)=r,则状态值的总和被r除所得余数将保持不变。若(m,n)=R,则将灯盏按照被R除所得余数分为R组,不同组的状态值总和被k除所得余数将保持相同或不同。故要使得经过有限次操作能使恰有一盏灯的状态发生改变,必须有r=R=1。
充分性:若m与k互质,则总可以进行“全部按一遍”的操作使得所有灯的状态发生改变,且如此操作(k-1)次,每盏灯都将遍历k个状态。若m与n互质,则可进行“连续按”操作使得只有一盏比其余盏多切换一次。因此可以经过有限次操作使恰有一盏灯的状态发生改变。
《原神》游戏中的“紫立方体”解密基本满足这一套路。如果在游玩过程中发现m与n与k的关系不符合结论,或许你就需要寻找被藏起来的其他方块了。
记开灯为 ,关灯为 ,则可以用一个长度为 的列向量来表示所有灯的状况,并记
那么这构成了一个特征为 的域
则每一次操作都相当于加上了向量组
中的一个向量,所以只要考虑问题:向量组
是否构成线性空间 的一组基?因为一旦它们构成了一组基,那么假设初始状态为 ,最终状态为 ,那么方程组
有解,其中
为这组向量组构成的矩阵
计算可得
所以答案是可以的
下面来编程实现一下
a=0; for i=1:7 for j=1:3 a(i,mod(i+j-4,7)+1)=1; end end %生成矩阵 t=inv(a)*3; t=round(t); t=mod(t,2); %计算逆矩阵 b=[1,0,1,1,1,1,0]; result=mod(round(t*b'),2); mod(a*result,2) %测试
最后输出的结果为
ans = 1 0 1 1 1 1 0
也的确是正确的
这里
t = inv ( a ) * 3 ;
是我在事先计算了a的逆之后,为了保证所有的元素都是整数才乘上去的,这样方便取模
此外从这个建模本身可以看出,操作的先后顺序是可以交换的,尽管直观上这很难想象
对于一般的情况,从上面的证明可以看出在给定了规则,初始状态和目标状态后,最后问题就变成了计算一个 上的行列式
更一般的,假设灯有 个状态,那么问题就转化成了计算一个特征为 的域 上的矩阵的行列式,而具体的操作就变成了解一个 上的线性方程组
考虑这个推广是因为我在玩原神的时候遇到了这样的问题:
每个正方体有一个紫色面,攻击其中的一个正方体就会导致和这个正方体及其相邻的两个正方体顺时针转动,现在要使四个正方体的紫色面都背对着角色
记面对着角色的位置为状态 ,顺时针旋转了 次后的位置为状态 , ,并且假设左下角的第一个正方体为第一个正方体,左上角的正方体为第二个正方体...以此类推,那么结果观察,初始状态就是 ,需要达到的状态就是 ,并且攻击第一个正方体就相当于在原来的状态上加上了 ,攻击第二个正方体就相当于在原来的状态上加上了 ,以此类推...注意正方体有四个状态,所以这里的任何运算都要视为在特征为 的域上做的
总之,这样一来问题就变成了求解线性方程组
计算代码如下
A = [1,1,0,1 1,1,1,0 0,1,1,1 1,0,1,1]; end_status = [2;2;2;2]; begin_status = [3;1;1;3]; B = mod(round(inv(A)),4); C = B*(end_status -begin_status); D = mod(C,4);
解得 (这是巧合吗?)
也就是攻击第一个正方体 下,第二个正方体 下,第三个正方体 下,第四个正方体 下就可以了
验证得确实如此