1. 程式人生 > >C語言猜牌術程式碼解析

C語言猜牌術程式碼解析

問題描述

魔術師利用一副牌中的13張黑桃,預先將它們排好後迭在一起,並使牌面朝下。然後他對觀眾說:我不看牌,只要數數就可以猜到每張牌是什麼,我大聲數數,你們聽,不信?

你們就看,魔術師將最上面的那張牌數為1,把它翻過來正好是黑桃A,他將黑桃A放在桌子上,然後按順序從上到下數手中的餘牌,第二次數1、2,將第一張牌放在這迭牌的下面,將第二張牌翻過來,正好是黑桃2,也將它放在桌子上,第三次數1、2、3,將前面兩張依次放在這迭牌的下面,再翻第三張牌正好是黑桃3,這樣依次進行,將13張牌全部翻出來,準確無誤。問魔術師手中的牌原始次序是怎樣安排的?

問題分析

題目中描述的內容比較多,但已經將魔術師出牌的過程描述的很清楚了。

假設桌子上有13個空盒子排成一圈,設定其中一個盒子序號為1,將黑桃A放入1號盒子中,接著從下一個空盒子開始重新計數,當數到第2個空盒子時,將黑桃2放入其中。然後再從下一個空盒子開始重新計數,數到第3個空盒子時,將黑桃3放入其中,這樣依次進行下去,直到將13張牌全部放入空盒子中為止。需要注意的是,在計數過程中要跳過那些已放入牌的盒子,而只對空盒子計數。最後牌在盒子中的順序,就是魔術師手中牌的順序。

演算法分析

根據問題分析,使用迴圈結構來實現程式。使用程式將分析過程模擬出來,就可以計算出魔術師手中牌的原始次序。由於有13張牌,因此顯然要迴圈13次,每次迴圈時找到與牌序號對應的那個空盒子,因此迴圈體完成的功能就是找到對應的空盒子將牌存入。

程式流程圖:

下面是完整的程式碼:

#include<stdio.h>

int a[14];

int main()
{
    int i, j=1, n;
    printf("魔術師手中的牌原始次序是:\n");
    for( i=1; i<=13; i++ )
    {
        n=1;
        do
        {
            if(j>13)
                j=1;
            if(a[j])  /*盒子非空*/
                j++;
            else  /*盒子為空*/
            {
                if(n==i)
                    a[j]=i;
                j++;
                n++;
            }
        }
        while(n<=i);
    }
    for( i=1; i<=13; i++ )
        printf("%d ", a[i]);
    printf("\n");
 
    return 0;
}

執行結果:

魔術師手中的牌原始次序是:
1 8 2 5 10 3 12 11 9 4 7 6 13 

C語言猜牌術程式碼解析