完美洗牌问题学习笔记

问题背景

完美洗牌 :一副 52 张的排序好的扑克牌,从中间分为两半,每部分各 26 张。假设每次都分为左右两部分,然后将

右部分的牌和左部分的牌按顺序交错穿插,每张左部分牌后面加入一张右部分的,依序加入所有右部分牌。

完成一次穿插后得到新的牌堆。

一副排序好的扑克牌(52张),在完成第 8 次完美洗牌后,将得到和初始顺序一致的牌堆。

解答目标

求出一个通用算法:

给出任意数量的扑克牌,求经过多少次完美洗牌后恢复原序

数据打样分析

将扑克牌按顺序编号为 0 ~ 51,8 次完美洗牌的中间过程如下

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

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

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

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

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

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

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

8: [0, 1, 2, 3, 4, 5, 6, 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]

第 8 次开始倒着分析,初始每个数据相差 1,

第 7 次各个数据的间隔变为 2 的 1 次方;

第 6 次各个数据的间隔变为 2 的 2 次方;

第 5 次各个数据的间隔变为 2 的 3 次方;

第 4 次各个数据的间隔变为 2 的 4 次方;

第 3 次各个数据的间隔变为 2 的 5 次方(32) mod 51 = 32;

第 2 次各个数据的间隔变为 2 的 6 次方(64) mod 51 = 13;

第 1 次各个数据的间隔变为 2 的 7 次方(128) mod 51 = 26;

第 0 次各个数据的间隔变为 2 的 8 次方(256) mod 51 = 1; (原始顺序)

可见反过来分析后,经过 8 次完美洗牌后,扑克牌又变回了原始顺序,

总结上面的算法,得到模数公式如下,设需要经过 n + 1 次完美洗牌后,一副 m 张扑克牌的排序变为原始排序, m 为偶数。
2 n ≡ m 2 ( m o d m − 1 ) 2^n \equiv \frac{m}{2} \pmod{m-1} 2n≡2m(modm−1)

转为数学计算公式
( m − 1 ) ∣ 2 n − m 2 2 n − m 2 = ( m − 1 ) k , k ∈ z , n > = m 2 (m - 1) | 2^n - \frac{m}{2} \\ 2^n - \frac{m}{2} = (m - 1)k, k \in z, n >= \sqrt{\frac{m}{2}} (m−1)∣2n−2m2n−2m=(m−1)k,k∈z,n>=2m

编程计算

py 复制代码
def test():
    # 51 | 2 ** n - 26 

    m = 52
    b = m // 2
    c = m - 1
    n = math.floor(math.sqrt(b))
    while True:

        a = 2 ** n
        if (a - b) % c == 0:
            print("success", n)
            break
        n += 1

## res:
## success 7

可以求得在 m 等于 52 时,n 等于 7, 即 52 张扑克牌经过 n + 1 = 8 次完美洗牌后会恢复原始排序。

拓展学习

上面的分析是基于 0 ~ 51 的编号,也就是和原始的扑克牌花色点数没有关系,任意 52 张扑克牌做了 8 次完美洗牌后,都会恢复到原始的序位。

可以将扑克牌的数量增加 8 张,相当于每种花色多了 2 张牌,这时扑克牌的总数是 60 张,套入上面的算法可以求得经过 58 次完美洗牌后,60 张牌会和未洗牌的顺序一样。

还可以深入研究的点:

  1. 什么情况下会无解
  2. 在小于 52 张的时候,什么情况无解
  3. 是否存在从某个数 x x x 开始,当扑克牌的数量 n > = x n >= x n>=x 时, 再也找不到解
相关推荐
壹玖玖肆26 分钟前
openGauss使用笔记
笔记
宵时待雨30 分钟前
linux笔记归纳17:传输层协议UDP
linux·笔记·udp
Asize41 分钟前
146. LRU 缓存
算法
Asize43 分钟前
543. 二叉树的直径
算法
lemon_sjdk1 小时前
ObjectProperty
java·开发语言·算法
Zentceh1 小时前
AI-ISP在夜视机芯中的应用:从传统ISP到PixelClean全彩夜视的进化
人工智能·科技·算法·计算机视觉·车载系统·视频·智能硬件
xier_ran2 小时前
【infra之路】AWQ 详解:激活感知权重保护,让 W4A16 量化精度超越 GPTQ
线性代数·算法·机器学习·量化·infra
亦皓ai2 小时前
AI时代后端工程(二):AI把代码写得越来越快,我却越来越不敢让它直接开工了
人工智能·算法·机器学习·搜索引擎·transformer
噜~噜~噜~2 小时前
操作系统笔记-2.3.2.1 进程互斥的软件实现方法
笔记·操作系统
小弥儿2 小时前
GitHub今日热榜 | 2026-08-26:AI 大脑与知识管理扎堆
人工智能·学习·开源·github