1.魔术师发牌-问题来源?
魔术师利用一副牌中的13张黑桃牌,预先将他们排好后叠放在一起,牌面朝下。对观众说:“我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将牌堆最上面的那张排数为1,把他翻过来正好是黑桃A,将黑桃A从牌堆抽出放在桌子上,第二次数1、2,将第一张放在牌堆最下面,第二张翻开,正好是黑桃2,也将它抽出放在桌子上。这样依次进行将13将牌全部翻出,准确无误。问牌最开始的顺序是怎样排的。
简单点说:
把13张牌按照一定的顺序排好,然后依次取牌,将每次取到的牌放在最下面,情形如下:
数一次,取牌,黑桃1,放牌堆最下面
数两次,取牌,黑桃2,放牌堆最下面
数三次,取牌,黑桃3,放牌堆最下面
数四次,取牌,黑桃4,放牌堆最下面
…直到取到最后的黑桃13(黑桃K),表演结束
2.我时昨天浏览网页,无意中看到了这个,百思不得其解,于是花了一些时间在网上寻找思路。
有一个我容易理解的方法如下,希望对你们有所帮助。我是在下面的网址找到的思路。
https://www.2cto.com/kf/201512/453519.html
主要内容如下:
看到这个方法,我恍然大悟,原来一个难的问题,只要有正确的解题思路,也可以变的很简单。
当然这个问题还有其它更好的解法,但是我暂时只学了这个。
于是就用c#语言写了代码如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace DrawingTest {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
Fp();
}
public void Fp() {
int[] poker = new int[13];
for (int i = 0; i < 13; i++) {
poker[i] = 0; //初始化所有的牌为0
}
poker[0] = 1; //第一个牌为1
int n = 0;
for (int i = 2; i <= 13; i++) { //魔术师第m次
for (int j=0; j < i; ) { //拿m次,前m-1次不要,第m次插牌
if (poker[n] == 0) { //前m-1次 (poker=0)不要
j++; //如果到达了最后一次
if (j == i) { //如果已经到了第m次(poker=0),插入m牌
poker[n] = i;
break;
}
}
//poker不为0证明有牌已经插入,跳过
n++;
if (n==13) {
n = 0;
}
}
}
MessageBox.Show(String.Join(",",poker));
}
}
}