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