列印魔方陣
乙個奇數階(設為n階)的方陣,將1、2、3……n2填入方陣中,使每行、每列資料之和都相等,這樣的方陣便是魔方陣。
例項解析:
填寫魔方陣有乙個固定的方法:
(1)1總是位於第一行的中間。
(3)若右上方超出**的右邊界,則數字填入到第一列,行數不變。圖16-1中的3和8都是這種情況。
若右上方超出上邊界,則數字填入最後一行,列數不變。圖16-1中2和9都是這種情況。
下面是程式**:
#define n 19
int main()
, i, j, k, n;
/*陣列元素全部初始化為0,表示沒有資料填入*/
scanf("%d",&n); //輸入方陣階數(奇數)
i = 0; //1的行數應該是0
j = n/2; //計算1應該在的列數
a[i][j] = 1; //將1填入表中
for(k = 2; k <= n*n; k++)
a[i][j] = k; //將k填入
}for(i = 0; i < n; i++)
getch();
return 0;
}
猜數遊戲
隨機生成乙個0~100之間的數,由使用者猜,允許猜5次,每次猜大了或猜小了,都要給出提示。最後,無論猜對或猜錯,都給出正確答案。
例項解析:
隨機數的生成可利用例項11所介紹的知識。使用者猜數可用迴圈,最多5次,若某次猜中則break。
#include #include #include int main()
if(i <= 5) //因break而退出
printf(「\n恭喜您,猜對了! 答案正是%d\n」, n);
else //迴圈自然退出
printf(「\n抱歉,沒猜對! 正確答案是%d\n」, n);
getch();
return 0;
}
二維陣列的排序輸出
有10名學生,每個學生考試三門功課:數學、英語、計算機,鍵盤輸入學號和成績(學號和分數都是整數),按總分高低排序輸出。
例項解析:
本題目需要完成輸入、排序和輸出。由於每個學生有5項資料:學號、三門成績、總分,儲存10個人的資料需要乙個二維陣列:
int a[11][5]; //第0行閒置不用
設計思路:
陣列的第0列用來存學號,第1~3列存單科成績,第4列存總分。
所有資料從鍵盤輸入,用迴圈實現,迴圈的同時計算每個人的總分。
排序用選擇法,與一維陣列不同的是,這裡的排序如果需要交換資料,那麼交換的是兩行的資料,而不是僅交換總分。
下面是程式**:
# define number 10
int main()
for(i = 1; i < number; i++)
}printf(" 學號 數學 英語 計算機 總分 名次\n");
for(i = 1; i <= number; i++)
for(j = 0; j <= 5; j++)
getch();
return 0;
}
尋找假幣
80枚硬幣中有一枚假幣,假幣比真幣稍輕,請用天平稱4次,將假幣找出。
天平兩邊都可以放硬幣
例項解析:
要用天平稱4次找出假幣,必須這樣稱:
(1) 將硬幣分成三組:27、27、26,將前兩組硬幣分放在天平兩側稱量,可以確定假幣在某一組,假幣範圍縮小到27(26)個硬幣中。
(2) 將假幣所在組再分三組9、9、9(或9、9、8),前兩組放天平上稱量,又可以確定假幣在哪一小組,假幣範圍縮小為9(8)個硬幣之中。
(3) 繼續分組3、3、3(或3、3、2),可確定假幣在3(2)個中。
(4) 繼續分組1、1、1(或1、1、0),便能找出假幣。
上面描述的是用天平找出假幣的方法,但計算機不是天平,要用計算機程式設計解這個題,就需要用程式來模擬天平稱量的過程,故必須先建立數學模型。
天平稱重,其實是比較兩邊硬幣的總重量是否相等。為了能計算總重量,我們定義乙個陣列,每個元素儲存乙個硬幣的重量,並使真幣的重量為1,假幣重量為0(只要比真幣輕即可),然後按照上面的方法分組4次,稱量4次。每次稱完,都用k記錄下假幣所在小組中第一枚硬幣的序號,以便下次分組從k開始。
下面為程式**:
#include "time.h"
#include "stdlib.h"
int main()
if(s1 > s2) //假幣在第2組
k += m;
if(s1 == s2) //假幣在第3組
k += 2*m;
m /= 3; //繼續分組,下次迴圈每組m/3個硬幣
}printf("假幣的序號是:%d\n", k);
getch();
return 0;
}
計算矩陣相乘
程式設計序計算矩陣相乘: a3×4×b4×2= c3×2
例項解析:
每個矩陣可用乙個陣列表示,陣列c中每一項都是累加的結果,因此c陣列中的資料必須先全部初始化為0。
c陣列中的某一項c[i][j]的值由a的第i行和b的第j列相乘而得。即:c[i][j] = a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]*b[3][j],此式的計算可用迴圈實現:
for(k =0; k<=3; k++)
c[i][j] += a[i][k] * b[k][j];
上面只是求得陣列c中的一項,利用迴圈可求出所有的資料。
程式**:
#define m 3
#define k 4
#define n 2
int main()
; int b[k][n] = , c[m][n] = ;
int i, j, k;
clrscr();
for(i = 0; i < m; i++)
printf(「\n」);
}getch();
return 0;
}
向排好序的陣列中插入資料
陣列中已按從小到大順序存有10個整數,鍵盤輸入乙個整數插入到陣列中,插入後的資料還是按順序排列的。
例項解析:
解法1:
要向排好序的資料中插入乙個資料x,必須首先確定x應該插入到陣列的何處,然後再行插入。
要確定x應插入到何處,需要將x依次與陣列中的每個元素進行比較,若x小於某元素,則該元素的位置便是x應該插入的位置。這個過程可用下面**實現。
for(i = 0; i <= 9; i++)
if(x < a[i])
break;
迴圈結束後,i的值便是x插入後的序號,即a[i]應當儲存x。
但是,此時還不能將x存入a[i],因為這樣做就把a[i]原值覆蓋了。正確的做法是,先把a[i]後移,然後再存入x。但是,如果a[i]後移到a[i+1],就把a[i+1]覆蓋了,如何解決?
可以從陣列最後乙個資料開始向後移動,即先把最後乙個後移,再把倒數第二個資料後移……
可用下面**實現:
k = i; //用k記錄下i的值,以便後面迴圈再用i作迴圈變數
for(i = 9; i >= k; i--)
a[i+1] = a[i];
完成這一步後,便可以把x插入到a[k]了:
a[k] = x;
下面是完整的程式**:
#include int main()
; int x, i, k;
scanf(「%d」, &x);
for(i = 0; i <= 9; i++)
if(x < a[i])
break;
k = i;
for(i = 9; i >= k; i--) /*自第k個資料之後的所有資料後移*/
a[i+1] = a[i];
a[k] = x; //將x插入
for(i = 0; i <= 10; i++)
printf(「%5d」, a[i]);
getch();
return 0;
}
解法2:
將陣列的元素從最後乙個開始依次與x比較,若陣列元素大於x,則後移,直到遇到乙個不大於x的元素或所有元素都比較完了為止。
for(i = 9; i >= 0 && a[i] > x; i--)
a[i + 1] = a[i];
當迴圈結束時,存在兩種情況:
(1)遇到乙個元素,使得a[i]不大於x,此時,x應插入到a[i+1]。
(2)所有元素都比較完了,使得x<0退出迴圈,x應插入到a[0],亦即a[i+1]。
兩種情況都可以用a[i+1] = x; 來完成插入。
解法二的主要**為:
for(i = 9; i >= 0 && a[i] > x; i--)
a[i+1] = a[i];
a[i+1] = x;
本文出自 「成鵬致遠」 部落格,請務必保留此出處
演算法 演算法的藝術(三)
列印魔方陣 乙個奇數階 設為n階 的方陣,將1 2 3 n2填入方陣中,使每行 每列資料之和都相等,這樣的方陣便是魔方陣。例項解析 填寫魔方陣有乙個固定的方法 1 1總是位於第一行的中間。3 若右上方超出 的右邊界,則數字填入到第一列,行數不變。圖16 1中的3和8都是這種情況。若右上方超出上邊界,...
演算法 演算法的藝術
小續 最近很多人都在問我資料結構和演算法的相關問題,對於初學者,貌似聽到演算法,資料結構什麼的,都覺得是比較高深的東西,其實它們並沒有想象中的難,只是你還沒有乙個整體上的把握,還沒有習慣站在整體上去思考問題。演算法是靈魂,資料結構是包裝,語言只是工具,學什麼語言並不重要,重要的是思想。這也是如鵬的理...
演算法 演算法的藝術(五)
利用位運算求整數的原碼或補碼 利用位運算求任意整數的原碼或補碼。例項解析 整數在記憶體中本來就是用補碼存放的,若要求出補碼,只需求出記憶體中的每一位二進位制數即可。而原碼,若是負數,則需要將補碼減1然後取反 最高位不取反 程式 include stdio.h int main while k 1 k...