1. 程式人生 > >C#:魔術師發牌-解法思路

C#:魔術師發牌-解法思路

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));
        }

    }

}