CC語言經(jīng)典、實(shí)用、趣味程序設(shè)計(jì)編程百例精解_第1頁
CC語言經(jīng)典、實(shí)用、趣味程序設(shè)計(jì)編程百例精解_第2頁
CC語言經(jīng)典、實(shí)用、趣味程序設(shè)計(jì)編程百例精解_第3頁
CC語言經(jīng)典、實(shí)用、趣味程序設(shè)計(jì)編程百例精解_第4頁
CC語言經(jīng)典、實(shí)用、趣味程序設(shè)計(jì)編程百例精解_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、C/C+語言經(jīng)典、實(shí)用、趣味程序設(shè)計(jì)編程百例精解(18)86.自動發(fā)牌一副撲克有52張牌,打橋牌時(shí)應(yīng)將牌分給四個人。請?jiān)O(shè)計(jì)一個程序完成自動發(fā)牌的工作。要求:黑桃用S(Spaces)表示;紅桃用H(Hearts)表示;方塊用D(Diamonds)表示;梅花用C(Clubs)表示。*問題分析與算法設(shè)計(jì)按照打橋牌的規(guī)定,每人應(yīng)當(dāng)有13張牌。在人工發(fā)牌時(shí),先進(jìn)行洗牌,然后將洗好的牌按一定的順序發(fā)給每一個人。為了便于計(jì)算機(jī)模擬,可將人工方式的發(fā)牌過程加以修改:先確定好發(fā)牌順序:1、2、3、4;將52張牌順序編號:黑桃2對應(yīng)數(shù)字0,紅桃2對應(yīng)數(shù)字1,方塊2對應(yīng)數(shù)字2,梅花2對應(yīng)數(shù)字3,黑桃3對應(yīng)數(shù)字4,紅

2、桃3對應(yīng)數(shù)字5,然后從52 張牌中隨機(jī)的為每個人抽牌。這里采用C語言庫函數(shù)的隨機(jī)函數(shù),生成0到51之間的共52個隨機(jī)數(shù),以產(chǎn)生洗牌后發(fā)牌的效果。*程序與程序注釋 #include#includeint comp(const void *j,const void *i);void p(int b,char n);int main(void)static char n=2,3,4,5,6,7,8,9,T,J,Q,K,A;int a53,b113,b213,b313,b413;int b11=0,b22=0,b33=0,b44=0,t=1,m,flag,i;while(t=52) /*控制發(fā)52張牌

3、*/m=rand()%52; /*產(chǎn)生0到51之間的隨機(jī)數(shù)*/for(flag=1,i=1;i=t&flag;i+)/*查找新產(chǎn)生的隨機(jī)數(shù)是否已經(jīng)存在*/if(m=ai) flag=0; /*flag=1:產(chǎn)生的是新的隨機(jī)數(shù)flag=0:新產(chǎn)生的隨機(jī)數(shù)已經(jīng)存在*/if(flag)at+=m; /*如果產(chǎn)生了新的隨機(jī)數(shù),則存入數(shù)組*/if(t%4=0) b1b11+=at-1; /*根據(jù)t的模值,判斷當(dāng)前*/else if(t%4=1) b2b22+=at-1; /*的牌應(yīng)存入哪個數(shù)組中*/else if(t%4=2) b3b33+=at-1;else if(t%4=3) b4b44+=at-1

4、;qsort(b1,13,sizeof(int),comp); /*將每個人的牌進(jìn)行排序*/qsort(b2,13,sizeof(int),comp);qsort(b3,13,sizeof(int),comp);qsort(b4,13,sizeof(int),comp);p(b1,n); p(b2,n); p(b3,n); p(b4,n); /*分別打印每個人的牌*/return 0;void p(int b,char n)int i;printf(n006 ); /*打印黑桃標(biāo)記*/for(i=0;i13;i+) /*將數(shù)組中的值轉(zhuǎn)換為相應(yīng)的花色*/if(bi/13=0) printf(%c

5、 ,nbi%13); /*該花色對應(yīng)的牌*/printf(n003 ); /*打印紅桃標(biāo)記*/for(i=0;i13;i+)if(bi/13)=1) printf(%c ,nbi%13);printf(n004 ); /*打印方塊標(biāo)記*/for(i=0;i13;i+)if(bi/13=2) printf(%c ,nbi%13);printf(n005 ); /*打印梅花標(biāo)記*/for(i=0;i13;i+)if(bi/13=3|bi/13=4) printf(%c ,nbi%13);printf(n);int comp(const void *j,const void *i) /*qsort調(diào)

6、用的排序函數(shù)*/return(*(int*)i-*(int*)j);87.黑白子交換有三個白子和三個黑子如下圖布置: . 游戲的目的是用最少的步數(shù)將上圖中白子和黑子的位置進(jìn)行交換: . 游戲的規(guī)則是:(1)一次只能移動一個棋子; (2)棋子可以向空格中移動,也可以跳過一個對方的棋子進(jìn)入空格,但不能向后跳,也不能跳過兩個子。請用計(jì)算機(jī)實(shí)現(xiàn)上述游戲。*問題分析與算法設(shè)計(jì)計(jì)算機(jī)解決勝這類問題的關(guān)鍵是要找出問題的規(guī)律,或者說是要制定一套計(jì)算機(jī)行動的規(guī)則。分析本題,先用人來解決問題,可總結(jié)出以下規(guī)則:(1) 黑子向左跳過白子落入空格,轉(zhuǎn)(5)(2) 白子向右跳過黑子落入空格,轉(zhuǎn)(5)(3) 黑子向左移動

7、一格落入空格(但不應(yīng)產(chǎn)生棋子阻塞現(xiàn)象),轉(zhuǎn)(5)(4) 白子向右移動一格落入空格(但不應(yīng)產(chǎn)生棋子阻塞現(xiàn)萌),轉(zhuǎn)(5)(5) 判斷游戲是否結(jié)束,若沒有結(jié)束,則轉(zhuǎn)(1)繼續(xù)。所謂的“阻塞”現(xiàn)象就是:在移動棋子的過程中,兩個尚未到位的同色棋子連接在一起,使棋盤中的其它棋子無法繼續(xù)移動。例如按下列方法移動棋子:0 . 1 . 2 . 3 . 4 兩個連在一起產(chǎn)生阻塞 . 或4 兩個白連在一起產(chǎn)生阻塞 . 產(chǎn)生阻塞的現(xiàn)象的原因是在第2步(狀態(tài))時(shí),棋子不能向右移動,只能將向左移動。總結(jié)產(chǎn)生阻塞的原因,當(dāng)棋盤出現(xiàn)“黑、白、空、黑”或“白、空、黑、白”狀態(tài)時(shí),不能向左或向右移動中間的棋子,只移動兩邊的棋子。

8、按照上述規(guī)則,可以保證在移動棋子的過程中,不會出現(xiàn)棋子無法移動的現(xiàn)象,且可以用最少的步數(shù)完成白子和黑子的位置交換。*程序說明與注釋#includeint number;void print(int a);void change(int *n,int *m);int main()int t7=1,1,1,0,2,2,2; /*初始化數(shù)組1:白子 2:黑子 0:空格*/int i,flag;print(t);while(t0+t1+t2!=6|t4+t5+t6!=3) /*判斷游戲是否結(jié)束若還沒有完成棋子的交換則繼續(xù)進(jìn)行循環(huán)*/flag=1; /*flag 為棋子移動一步的標(biāo)記1:尚未移動棋子 0

9、:已經(jīng)移動棋子*/for(i=0;flag&i5;i+) /*若白子可以向右跳過黑子,則白子向右跳*/if(ti=1&ti+1=2&ti+2=0)change(&ti,&ti+2); print(t); flag=0;for(i=0;flag&i5;i+) /*若黑子可以向左跳過白子,則黑子向左跳*/if(ti=0&ti+1=1&ti+2=2)change(&ti,&ti+2); print(t); flag=0;for(i=0;flag&i6;i+) /*若向右移動白子不會產(chǎn)生阻塞,則白子向右移動*/if(ti=1&ti+1=0&(i=0|ti-1!=ti+2)change(&ti,&ti+

10、1); print(t);flag=0;for(i=0;flag&i6;i+) /*若向左移動黑子不會產(chǎn)生阻塞,則黑子向左移動*/if(ti=0&ti+1=2&(i=5|ti-1!=ti+2) change(&ti,&ti+1); print(t);flag=0;void print(int a)int i;printf(No. %2d:.n,number+);printf( );for(i=0;i=6;i+)printf( | %c,ai=1?*:(ai=2?: );printf( |n .nn);void change(int *n,int *m)int term;term=*n; *n=

11、*m; *m=term;*問題的進(jìn)一步討論本題中的規(guī)則不僅適用于三個棋子的情況,而且可以推而廣之,適用于任意N個棋子的情況。讀者可以編程驗(yàn)證,按照本規(guī)則得到的棋子移動步數(shù)是最少的。事實(shí)上,制定規(guī)則是解決這類問題的關(guān)鍵。一個游戲程序“思考水平的高低,完全取決于使用規(guī)則的好壞?!?思考題有兩個白子和兩個黑子如下左圖布置: . . . . . 棋盤中的棋子按”馬步“規(guī)則行走,要求用最少的步數(shù)將圖中白子和黑子的位置進(jìn)行交換,最終結(jié)果如下一幅圖所示。 . . . . . 88.常勝將軍現(xiàn)有21根火柴,兩人輪流取,每人每次可以取走1至4根,不可多取,也不能不取,誰取最后一楰火柴誰輸。請編寫一個程序進(jìn)行人機(jī)

12、對弈,要求人先取,計(jì)算機(jī)后取;計(jì)算機(jī)一方為“常勝將軍”。*問題分析與算法設(shè)計(jì)在計(jì)算機(jī)后走的情況下,要想使計(jì)算機(jī)成為“常勝將軍”,必須找出取 關(guān)鍵。根據(jù)本題的要求枷以總結(jié)出,后走一方取子的數(shù)量與對方剛才一步取子的數(shù)量之和等于,就可以保證最后一個子是留給先取子的那個人的。據(jù)此分析進(jìn)行算法設(shè)計(jì)就是很簡單的工作,編程實(shí)現(xiàn)也十分容易。*程序說明與注釋#includeint main()int a=21,i;printf(Game begin:n);while(a0)doprintf(How many stick do you wish to take(1%d)?,a4?4:a);scanf(%d,&i)

13、;while(i4|ia); /*接收正在確的輸入*/if(a-i0) printf( %d stick left in the pile.n,a-i);if(a-i)=0)printf( You have taken the last stick.n);printf( * * * You lose! nGame Over.n); /*輸出取勝標(biāo)記*/break;elseprintf( Compute take %d stick.n,5-i); /*輸出計(jì)算機(jī)取的子數(shù)*/a-=5;printf( %d stick left in the pile.n,a);*思考題改變題目中火柴的數(shù)量(如為2

14、2根),則后走的一方就不一定能夠保持常勝了,很可能改變成“常敗”。此時(shí)后走一方的勝負(fù)就與火柴的初始數(shù)量和每次允許取的火柴數(shù)量的最大值有直接關(guān)系,請編寫程序解決這一問題。 89.搶30這是中國民間的一個游戲。兩人從1開始輪流報(bào)數(shù),每人每次可報(bào)一個數(shù)或兩個連續(xù)的數(shù),誰先報(bào)到30,誰就為勝方。*問題分析與算法設(shè)計(jì)本題與上題類似,算法也類似,所不同的是,本誰先走第一步是可選的。若計(jì)算機(jī)走第一步,那么計(jì)算機(jī)一定是贏家。若人先走一步,那么計(jì)算機(jī)只好等待人犯錯誤,如果人先走第一步且不犯錯誤,那么人就會取勝;否則計(jì)算機(jī)會抓住人的一次錯誤使自己成為勝利者。*程序說明與注釋#include#include#inc

15、ludeint input(int t);int copu(int s);int main()int tol=0;printf(n* * * * * * * *catch thirty* * * * * * * n);printf(Game Beginn);randomize(); /*初始化隨機(jī)數(shù)發(fā)生器*/if(random(2)=1) /*取隨機(jī)數(shù)決定機(jī)器和人誰先走第一步*/tol=input(tol); /*若為1,則余元走第一步*/while(tol!=30) /*游戲結(jié)束條件*/if(tol=copu(tol)=30) /*計(jì)算機(jī)取一個數(shù),若為30則機(jī)器勝利*/printf(I lo

16、se! n);elseif(tol=input(tol)=30) /*人取一個數(shù),若為30則人勝利*/printf(I lose! n);printf( * * * * * * * *Game Over * * * * * * * *n);int input(int t)int a;doprintf(Please count:);scanf(%d,&a);if(a2|a30)printf(Error input,again!);elseprintf(You count:%dn,t+a);while(a2|a30);return t+a; /*返回當(dāng)前的已經(jīng)取走的數(shù)累加和*/int copu(i

17、nt s)int c;printf(Computer count:);if(s+1)%3=0) /*若剩余的數(shù)的模為1,則取1*/printf( %dn,+s);else if(s+2)%3=0)s+=2; /*若剩余的數(shù)的模為2,則取2*/printf( %dn,s);elsec=random(2)+1; /*否則隨機(jī)取1或2*/s+=c;printf( %dn,s);return s;*思考題巧奪偶數(shù)。桌子上有25顆棋子,游戲雙方輪流取子,每人每次最少取走一顆棋子,最多可取走3顆棋子。雙方照這樣取下去,直到取光所有的棋子。于是雙方手中必然一方為偶數(shù),一方為奇數(shù),偶數(shù)方為勝者。請編程實(shí)現(xiàn)人機(jī)

18、游戲。90.搬山游戲設(shè)有n座山,計(jì)算機(jī)與人為比賽的雙方,輪流搬山。規(guī)定每次搬山的數(shù)止不能超 過k座,誰搬最后一座誰輸。游戲開始時(shí)。計(jì)算機(jī)請人輸入山的總數(shù)(n)和每次允許搬山的最大數(shù)止(k)。然后請人開始,等人輸入了需要搬走的山的數(shù)目后,計(jì)算機(jī)馬上打印出它搬多少座山,并提示尚余多少座山。雙方輪流搬山直到最后一座山搬完為止。計(jì)算機(jī)會顯示誰是贏家,并問人是否要繼續(xù)比賽。若人不想玩了,計(jì)算機(jī)便會統(tǒng)計(jì)出共玩了幾局,雙方勝負(fù)如何。*問題分析與算法設(shè)計(jì)計(jì)算機(jī)參加游戲時(shí)應(yīng)遵循下列原則:1) 當(dāng):剩余山數(shù)目-1=可移動的最大數(shù)k 時(shí)計(jì)算機(jī)要移(剩余山數(shù)目-1)座,以便將最后一座山留給人。2)對于任意正整數(shù)x,y

19、,一定有:0=x%(y+1)=y在有n座山的情況下,計(jì)算機(jī)為了將最后一座山留給人,而且又要控制每次搬山的數(shù)目不超過最大數(shù)k,它應(yīng)搬山的數(shù)目要滿足下列關(guān)系:(n-1)%(k+1)如果算出結(jié)果為0,即整除無余數(shù),則規(guī)定只搬1座山,以防止冒進(jìn)后發(fā)生問題。按照這樣的規(guī)律,可編寫出游戲程序如下:#includeint main()int n,k,x,y,cc,pc,g;printf(More Mountain Gamen);printf(Game Beginn);pc=cc=0;g=1;for(;)printf(No.%2d game n,g+);printf(n);printf(How many mpuntains are there?);scanf(%d,&n);if(!n) break;printf(How many mountains are allowed to each time?);doscanf(%d,&k);if(kn|kn|k1);doprintf(How many

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論