部分内容转载自:http://blog.csdn.net/sunnyyoona/article/details/43795243,代码重新使用C++实现。
题目
玩过扑克牌的朋友都知道,在一局完了之后洗牌,洗牌人会习惯性的把整副牌大致分为两半,两手各拿一半对着对着交叉洗牌,我们的问题是:如何才能保证依次洗牌过后左右手牌是一一交叉的呢?
2004年,microsoft的Peiyush Jain在他发表一篇名为:“A Simple In-Place Algorithm for In-Shuffle”的论文中提出了完美洗牌算法。
什么是完美洗牌问题呢?即给定一个数组a1,a2,a3,…an,b1,b2,b3..bn,最终把它置换成b1,a1,b2,a2,…bn,an。
对原始位置的变化做如下分析:
依次考察每个位置的变化规律:
a1:1 -> 2
a2:2 -> 4
a3:3 -> 6
a4:4 -> 8
b1:5 -> 1
b2:6 -> 3
b3:7 -> 5
b4:8 -> 7
对于原数组位置i的元素,新位置是(2*i)%(n+1),注意,这里用2n表示原数组的长度。后面依然使用该表述方式。有了该表达式,我们可以新建一个数组,然后遍历每一个元素&#x