Cc++趣味程序百例(獻給CC++初學者)_第1頁
Cc++趣味程序百例(獻給CC++初學者)_第2頁
Cc++趣味程序百例(獻給CC++初學者)_第3頁
Cc++趣味程序百例(獻給CC++初學者)_第4頁
Cc++趣味程序百例(獻給CC++初學者)_第5頁
已閱讀5頁,還剩131頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

Cc++趣味程序百例(獻給CC++初學者)Cc++趣味程序百例(獻給CC++初學者)Cc++趣味程序百例(獻給CC++初學者)Cc++趣味程序百例(獻給CC++初學者)編制僅供參考審核批準生效日期地址:電話:傳真:郵編:C/c++趣味程序百例(獻給C/C++初學者)1.繪製餘弦曲線

2.繪製餘弦曲線和直線

3.繪製圓

4.歌星大獎賽

5.求最大數(shù)

6.高次方數(shù)的尾數(shù)

7.階乘尾數(shù)零的個數(shù)

8.借書方案知多少

9.楊輝三角形

10.數(shù)制轉(zhuǎn)換

11.打魚還是曬網(wǎng)

12.抓交通肇事犯

13.該存多少錢

14.怎樣存錢利最大

15.捕魚和分魚

16.出售金魚

17.平分七筐魚

18.有限5位數(shù)

除不盡的自然數(shù)

20.一個奇異的三位數(shù)

位反序數(shù)

22.求車速

23.由兩個平方三位數(shù)獲得三個平方二位數(shù)

24.阿姆斯特朗數(shù)

25.完全數(shù)

26.親密數(shù)

27.自守數(shù)

28.回文數(shù)

29.求具有abcd=(ab+cd)2性質(zhì)的四位數(shù)

30.求素數(shù)

31.歌德巴赫猜想

32.可逆素數(shù)

33.回文素數(shù)

34.要發(fā)就發(fā)

35.素數(shù)幻方

36.百錢百雞問題

37.愛因斯坦的數(shù)學題

38.換分幣

39.年齡幾何

40.三色球問題

41.馬克思手稿中的數(shù)學題

42.最大公約數(shù)和最小公倍數(shù)

43.分數(shù)比較

44.分數(shù)之和

45.將真分數(shù)分解為埃及分數(shù)

46.列出真分數(shù)序列

47.計算分數(shù)的精確值

48.新娘和新郎

49.委派任務

50.誰在說謊

51.誰是竊賊

52.黑與白

53.迷語博士的難題(1)

54.迷語博士的難題(2)

55.哪個大夫哪天值班

56.區(qū)分旅客國籍

57.誰家孩子跑最慢

58.拉丁方陣

59.填表格

~9分成1:2:3的三個3位數(shù)

~9組成三個3位的平方數(shù)

62.由8個整數(shù)形成奇特的立方體

63.減式還原

64.乘式還原

65.乘式還原(2)

66.除式還原(1)

67.除式還原(2)

68.九位累進可除數(shù)

69.魔術師的猜牌術(1)

70.魔術師的猜牌術(2)

71.約瑟夫問題

72.郵票組合

73.和數(shù)能表示1~23的5個正整數(shù)

74.可稱1~40磅的4塊砝碼

個小孩分糖果

76.小明買書

77.波松瓦酒的分酒趣題

78.求π的近似值

79.求π的近似值(2)

80.奇數(shù)平方的一個有趣性質(zhì)

81.角谷猜想

82.四方定理

83.卡布列克常數(shù)

84.尼科徹斯定理

85.回文數(shù)的形成

86.自動發(fā)牌

87.黑白子交換

88.常勝將軍

89.搶30

90.搬山遊戲

91.人機猜數(shù)遊戲

92.人機猜數(shù)遊戲(2)

93.漢諾塔

94.兔子產(chǎn)子

95.將阿拉伯數(shù)字轉(zhuǎn)換為羅馬數(shù)字

96.選美比賽

97.滿足特異條件的數(shù)列

98.八皇后問題

99.超長正整數(shù)的加法

100.數(shù)字移動1.繪製餘弦曲線

在屏幕上用「*」顯示0~360度的餘弦函數(shù)cos(x)曲線

*問題分析與算法設計

如果在程序中使用數(shù)組,這個問題十分簡單。但若規(guī)定不能使用數(shù)組,問題就變得不容易了。

關鍵在於餘弦曲線在0~360度的區(qū)間內(nèi),一行中要顯示兩個點,而對一般的顯示器來說,只能按行輸出,

即:輸出第一行信息後,只能向下一行輸出,不能再返回到上一行。為了獲得本文要求的圖形就必須在一

行中一次輸出兩個「*」。

為了同時得到餘弦函數(shù)cos(x)圖形在一行上的兩個點,考慮利用cos(x)的左右對稱性。將屏幕的行方向定

義為x,列方向定義為y,則0~180度的圖形與180~360度的圖形是左右對稱的,若定義圖形的總寬度為62列

,計算出x行0~180度時y點的坐標m,那麼在同一行與之對稱的180~360度的y點的坐標就應為62-m。程序

中利用反餘弦函數(shù)acos計算坐標(x,y)的對應關係。

使用這種方法編出的程序短小精煉,體現(xiàn)了一定的技巧。

*程序說明與註釋

#include<>

#include<>

intmain()

{

doubley;

intx,m;

for(y=1;y>=-1;y-=/*y為列方向,值從1到-1,步長為*/

{

m=acos(y)*10;/*計算出y對應的弧度m,乘以10為圖形放大倍數(shù)*/

for(x=1;x<m;x++)printf("");

printf("*");/*控制打印左側的*號*/

for(;x<62-m;x++)printf("");

printf("*\n");/*控制打印同一行中對稱的右側*號*/

}

return0;

}

*思考題

如何實現(xiàn)用「*」顯示0~360度的sin(x)曲線。

在屏幕上顯示0~360度的cos(x)曲線與直線f(x)=45*(y-1)+31的迭加圖形。其中cos(x)圖形用「*」表示,

f(x)用「+」表示,在兩個圖形相交的點上則用f(x)圖形的符號。

2.繪製餘弦曲線和直線

*問題分析與算法設計

本題可以在上題的基礎上進行修改。圖形迭加的關鍵是要在分別計算出同一行中兩個圖形的列方向點坐標

後,正確判斷相互的位置關係。為此,可以先判斷圖形的交點,再分別控制打印兩個不同的圖形。

*程序註釋與說明

#include<>

#include<>

intmain()

{

doubley;

intx,m,n,yy;

for(yy=0;yy<=20;yy++)/*對於第一個y坐標進行計算並在一行中打印圖形*/

{

y=*yy;/*y:屏幕行方向坐標*/

m=acos(1-y)*10;/*m:cos(x)曲線上y點對應的屏幕列坐標*/

n=45*(y-1)+31;/*n:直線上y點對應的列坐標*/

for(x=0;x<=62;x++)/*x:屏幕列方向坐標*/

if(x==m&&x==n)printf("+");/*直線與cos(x)相交時打印「+」*/

elseif(x==n)printf("+");/*打印不相交時的直線圖形*/

elseif(x==m||x==62-m)printf("*");/*打印不相交時的cos(x)圖形*/

elseprintf("");/*其它情況打印空格*/

printf("\n");

}

return0;

}

*思考題

如何實現(xiàn)sin(x)曲線與cos(x)曲線圖形的同時顯示。

3.繪製圓

在屏幕上用「*」畫一個空心的圓

*問題分析與算法設計

打印圓可利用圖形的左右對稱性。根據(jù)圓的方程:

R*R=X*X+Y*Y

可以算出圓上每一點行和列的對應關係。

*程序說明與註釋

#include<>

#include<>

intmain()

{

doubley;

intx,m;

for(y=10;y>=-10;y–)

{

m=*sqrt(100-y*y);/*計算行y對應的列坐標m,是屏幕縱橫比調(diào)節(jié)係數(shù)因為屏幕的

行距大於列距,不進行調(diào)節(jié)顯示出來的將是橢圓*/

for(x=1;x<30-m;x++)printf("");/*圖形左側空白控制*/

printf("*");/*圓的左側*/

for(;x<30+m;x++)printf("");/*圖形的空心部分控制*/

printf("*\n");/*圓的右側*/

}

return0;

}

*思考題

實現(xiàn)函數(shù)y=x2的圖形與圓的圖形疊加顯示

4.歌星大獎賽

在歌星大獎賽中,有10個評委為參賽的選手打分,分數(shù)為1~100分。選手最後得分為:去掉一個最高分和

一個最低分後其餘8個分數(shù)的平均值。請編寫一個程序?qū)崿F(xiàn)。

*問題分析與算法設計

這個問題的算法十分簡單,但是要注意在程序中判斷最大、最小值的變量是如何賦值的。

*程序說明與註釋

#include<>

intmain()

{

intinteger,i,max,min,sum;

max=-32768;/*先假設當前的最大值max為C語言整型數(shù)的最小值*/

min=32767;/*先假設當前的最小值min為C語言整型數(shù)的最大值*/

sum=0;/*將求累加和變量的初值置為0*/

for(i=1;i<=10;i++)

{

printf("Inputnumber%d=",i);

scanf("%d",&integer);/*輸入評委的評分*/

sum+=integer;/*計算總分*/

if(integer>max)max=integer;/*通過比較篩選出其中的最高分*/

if(integer<min)min=integer;/*通過比較篩選出其中的最低分*/

}

printf("Canceledmaxscore:%d\nCanceledminscore:%d\n",max,min);

printf("Averagescore:%d\n",(sum-max-min)/8);/*輸出結果*/

}

*運行結果

Inputnumber1=90

Inputnumber2=91

Inputnumber3=93

Inputnumber4=94

Inputnumber5=90

Inputnumber6=99

Inputnumber7=97

Inputnumber8=92

Inputnumber9=91

Inputnumber10=95

Canceledmaxscore:99

Canceledminscore:90

Averagescore:92

*思考題

題目條件不變,但考慮同時對評委評分進行裁判,即在10個評委中找出最公平(即評分最接返平均分)和最

不公平(即與平均分的差距最大)的評委,程序應該怎樣實現(xiàn)?

5.求最大數(shù)

問555555的約數(shù)中最大的三位數(shù)是多少?

*問題分析與算法設計

根據(jù)約數(shù)的定義,對於一個整數(shù)N,除去1和它自身外,凡能整除N的數(shù)即為N的約數(shù)。因此,最簡單的方法

是用2到N-1之間的所有數(shù)去除N,即可求出N的全部約數(shù)。本題只要求取約數(shù)中最大的三位數(shù),則其取值范

圍可限制在100到999之間。

*程序說明與註釋

#include<>

intmain()

{

longi;

intj;

printf("Pleaseinputnumber:");

scanf("%ld",&i);

for(j=999;j>=100;j–)

if(i%j==0)

{

printf("Themaxfactorwith3digitsin%ldis:%d,\n",i,j);

break;

}

}

*運行結果

輸入:555555

輸出:Themaxfactorwith3digitsin555555is:777

6.高次方數(shù)的尾數(shù)

求13的13次方的最後三位數(shù)

*問題分析與算法設計

解本題最直接的方法是:將13累乘13次方截取最後三位即可。

但是由於計算機所能表示的整數(shù)範圍有限,用這種「正確」的算法不可能得到正確的結果。事實上,題目

僅要求最後三位的值,完全沒有必要求13的13次方的完整結果。

研究乘法的規(guī)律發(fā)現(xiàn):乘積的最後三位的值只與乘數(shù)和被乘數(shù)的後三位有關,與乘數(shù)和被乘數(shù)的高位無關

。利用這一規(guī)律,可以大大簡化程序。

*程序說明與註釋

#include<>

intmain()

{

inti,x,y,last=1;/*變量last保存求X的Y次方過程中的部分乘積的後三位*/

printf("InputXandY(X**Y):");

scanf("%d**%d",&x,&y);

for(i=1;i<=y;i++)/*X自乘Y次*/

last=last*x%1000;/*將last乘X後對1000取模,即求積的後三位*/

printf("Thelast3digitsof%d**%dis:%d\n",x,y,last%1000);/*打印結果*/

}

*運行結果

InputXandY(X**Y):13**13

Thelast3digitsof13**13is:253

InputXandY(X**Y):13**20

Thelast3digitsof13**20is:801

7.階乘尾數(shù)零的個數(shù)

100!的尾數(shù)有多少個零

*問題分析與算法設計

可以設想:先求出100!的值,然後數(shù)一下末尾有多少個零。事實上,與上題一樣,由於計算機所能表

示的整數(shù)範圍有限,這是不可能的。

為了解決這個問題,必須首先從數(shù)學上分析在100!結果值的末尾產(chǎn)生零的條件。不難看出:一個整

數(shù)若含有一個因子5,則必然會在求100!時產(chǎn)生一個零。因此問題轉(zhuǎn)化為求1到100這100個整數(shù)中包含了多

少個因子5。若整數(shù)N能被25整除,則N包含2個因子5;若整數(shù)N能被5整除,則N包含1個因子5。

*程序說明與註釋

#include<>

intmain()

{

inta,count=0;

for(a=5;a<=100;a+=5)n",count);

*問題進一步討論

本題的求解程序是正確的,但是存在明顯的缺點。程序中判斷整數(shù)N包含多少個因子5的方法是與程序中的

100有關的,若題目中的100改為1000,則就要修改程序中求因子5的數(shù)目的算法了。

*思考題

修改程序中求因子5的數(shù)目的算法,使程序可以求出任意N!的末尾有多少個零。

8.借書方案知多少

小明有五本新書,要借給A,B,C三位小朋友,若每人每次只能借一本,則可以有多少種不同的借法?

*問題分析與算法設計

本問題實際上是一個排列問題,即求從5個中取3個進行排列的方法的總數(shù)。首先對五本書從1至5進行編號

,然後使用窮舉的方法。假設三個人分別借這五本書中的一本,當三個人所借的書的編號都不相同時,就

是滿足題意的一種借閱方法。

*程序說明與註釋

intmain()

{

inta,b,c,count=0;

printf("TherearediffrentmethodsforXMtodistributebooksto3readers:\n");

for(a=1;a<=5;a++)/*窮舉第一個人借5本書中的1本的全部情況*/

for(b=1;b<=5;b++)/*窮舉第二個人借5本書中的一本的全部情況*/

for(c=1;a!=b&&c<=5;c++)/*當前兩個人借不同的書時,窮舉第三個人借5本書

中的1本的全部情況*/

if(c!=a&&c!=b)/*判斷第三人與前兩個人借的書是否不同*/

printf(count%8"%2d:%d,%d,%d":"%2d:%d,%d,%d\n",++count,a,b,c);

/*打印可能的借閱方法*/

}

*運行結果

TherearediffrentmethodsforXMtodistributebooksto3readers:

1:1,2,32:1,2,43:1,2,54:1,3,25:1,3,4

6:1,3,57:1,4,28:1,4,39:1,4,510:1,5,2

11:1,5,312:1,5,413:2,1,314:2,1,415:2,1,5

16:2,3,117:2,3,418:2,3,519:2,4,120:2,4,3

21:2,4,522:2,5,123:2,5,324:2,5,425:3,1,2

26:3,1,427:3,1,528:3,2,129:3,2,430:3,2,5

31:3,4,132:3,4,233:3,4,534:3,5,135:3,5,2

36:3,5,437:4,1,238:4,1,339:4,1,540:4,2,1

41:4,2,342:4,2,543:4,3,144:4,3,245:4,3,5

46:4,5,147:4,5,248:4,5,349:5,1,250:5,1,3

51:5,1,452:5,2,153:5,2,354:5,2,455:5,3,1

56:5,3,257:5,3,458:5,4,159:5,4,260:5,4,3

9.楊輝三角形

在屏幕上顯示楊輝三角形

1

11

121

1331

14641

15101051

………………..

*問題分析與算法設計

楊輝三角形中的數(shù),正是(x+y)的N次方冪展開式各項的係數(shù)。本題作為程序設計中具有代表性的題目,求

解的方法很多,這裡僅給出一種。

從楊輝三角形的特點出發(fā),可以總結出:

1)第N行有N+1個值(設起始行為第0行)

2)對於第N行的第J個值:(N>=2)

當J=1或J=N+1時:其值為1

J!=1且J!=N+1時:其值為第N-1行的第J-1個值與第N-1行第J個值

之和

將這些特點提煉成數(shù)學公式可表示為:

1x=1或x=N+1

c(x,y)=

c(x-1,y-1)+c(x-1,y)其它

本程序應是根據(jù)以上遞歸的數(shù)學表達式編製的。

*程序說明與註釋

#include<>

intmain()

{

inti,j,n=13;

printf("N=");

while(n>12)

scanf("%d",&n);/*控制輸入正確的值以保證屏幕顯示的圖形正確*/

for(i=0;i<=n;i++)/*控制輸出N行*/

{

for(j-0;j<24-2*i;j++)printf("");/*控制輸出第i行前面的空格*/

for(j=1;j<i+2;j++)printf("%4d",c(i,j));/*輸出第i行的第j個值*/

printf("\n");

}

}

voidintc(intx,inty)/*求楊輝三角形中第x行第y列的值*/

{

intz;

if((y==1)||(y==x+1))return1;/*若為x行的第1或第x+1列,則輸出1*/

z=c(x-1,y-1)+c(x-1,y);/*否則,其值為前一行中第y-1列與第y列值之和*/

returnz;

}

*思考題

自行設計一種實現(xiàn)楊輝三角形的方法

10.數(shù)制轉(zhuǎn)換

將任一整數(shù)轉(zhuǎn)換為二進制形式

*問題分析與算法設計

將十進制整數(shù)轉(zhuǎn)換為二進制的方法很多,這裡介紹的實現(xiàn)方法利用了C語言能夠?qū)ξ贿M行操作的特點。對

於C語言來說,一個整數(shù)在計算機內(nèi)就是以二進制的形式存儲的,所以沒有必要再將一個整數(shù)經(jīng)過一系列

的運算轉(zhuǎn)換為二進制形式,只要將整數(shù)在內(nèi)存中的二進製表示輸出即可。

*程序說明與註釋

#include<>

voidprintb(int,int);

intmain()

{

intx;printf("Inputnumber:");

scanf("%d",&x);

printf("numberofdecimalform:%d\n",x);

printf("it'sbinaryform:");

printb(x,sizeof(int)*8);/*x:整數(shù)sizeof(int):int型在內(nèi)存中所佔的字節(jié)數(shù)

sizeof(int)*8:int型對應的位數(shù)*/

putchar('\n');

}

voidprintb(intx,intn)

{

if(n>0)

{

putchar('0'+((unsigned)(x&(1<<(n-1)))>>(n-1)));/*輸出第n位*/

printb(x,n-1);/*歸調(diào)用,輸出x的後n-1位*/

}

}

*運行結果

輸入:8

輸出:

numberofdecimalform:8

it'sbunaryform:0000000000001000

輸入:-8

輸出:numberofdecimalform:-8

it'sbinaryform:000

輸入:32767

輸出:numberofdecimalform:32767

it'sbinaryform:011

輸入:-32768

輸出:numberofdecimalform:-32768

it'sbinaryform:000

輸入:128

輸出:numberofdecimalform:128

it'sbinaryform:00000000

*問題的進一步討論

充分利用C語言可以對位進行操作的特點,可以編寫許多其它高級語言不便於編寫甚至根本無法編寫的程

序。位操作是C語言的一大特點,在深入學習C語言的過程中應力求很好掌握。

程序中使用的位運算方法不是最佳的,也可以不用遞歸操作,大家可以自行對程序進行優(yōu)化。

*思考題

將任意正整數(shù)轉(zhuǎn)換為四進制或八進制數(shù)11.打魚還是曬網(wǎng)

中國有句俗語叫「三天打魚兩天曬網(wǎng)」。某人從1990年1月1日起開始「三天打魚兩天曬網(wǎng)」,問這個人在

以後的某一天中是「打魚」還是「曬網(wǎng)」。

*問題分析與算法設計

根據(jù)題意可以將解題過程分為三步:

1)計算從1990年1月1日開始至指定日期共有多少天;

2)由於「打魚」和「曬網(wǎng)」的週期為5天,所以將計算出的天數(shù)用5去除;

3)根據(jù)餘數(shù)判斷他是在「打魚」還是在「曬網(wǎng)」;

若餘數(shù)為1,2,3,則他是在「打魚」

否則是在「曬網(wǎng)」

在這三步中,關鍵是第一步。求從1990年1月1日至指定日期有多少天,要判斷經(jīng)歷年份中是否有閏年,二

月為29天,平年為28天。閏年的方法可以用偽語句描述如下:

如果((年能被4除盡且不能被100除盡)或能被400除盡)

則該年是閏年;

否則不是閏年。

C語言中判斷能否整除可以使用求余運算(即求模)

*程序說明與註釋

#include<>

intdays(structdateday);

structdate{

intyear;

intmonth;

intday;

};

intmain()

{

structdatetoday,term;

intyearday,year,day;

printf("Enteryear/month/day:");

scanf("%d%d%d",&,&,&;/*輸入日期*/

=12;/*設置變量的初始值:月*/

=31;/*設置變量的初始值:日*/

for(yearday=0,year=1990;year<;year++)

{

=year;

yearday+=days(term);/*計算從1990年至指定年的前一年共有多少天*/

}

yearday+=days(today);/*加上指定年中到指定日期的天數(shù)*/

day=yearday%5;/*求餘數(shù)*/

if(day>0&&day<4)printf("hewasfishingatthatday.\n");/*打印結果*/

elseprintf("Hewassleepingatthatday.\n");

}

intdays(structdateday)

{

staticintday_tab[2][13]=

{{0,31,28,31,30,31,30,31,31,30,31,30,31,},/*平均每月的天數(shù)*/

{0,31,29,31,30,31,30,31,31,30,31,30,31,},

};

inti,lp;

lp=%4==0&&%100!=0||%400==0;

/*判定year為閏年還是平年,lp=0為平年,非0為閏年*/

for(i=1;i<;i++)/*計算本年中自1月1日起的天數(shù)*/

+=day_tab[lp];

return;

}

*運行結果

Enteryear/month/day:19911025

Hewasfishingatday.

Enteryear/month/day:19921025

Hewassleepingatday.

Enteryear/month/day:19931025

Hewassleepingatday.

*思考題

請打印出任意年份的日曆

12.抓交通肇事犯

一輛卡車違反交通規(guī)則,撞人後逃跑?,F(xiàn)場有三人目擊事件,但都沒有記住車號,只記下車號的一些特徵

。甲說:牌照的前兩位數(shù)字是相同的;乙說:牌照的後兩位數(shù)字是相同的,但與前兩位不同;丙是數(shù)學

家,他說:四位的車號剛好是一個整數(shù)的平方。請根據(jù)以上線索求出車號。

*問題分析與算法設計

按照題目的要求造出一個前兩位數(shù)相同、後兩位數(shù)相同且相互間又不同的整數(shù),然後判斷該整數(shù)是否是另

一個整數(shù)的平方。

*程序說明與註釋

#include<>

#include<>

intmain()

{

inti,j,k,c;

for(i=1;i<=9;i++)/*i:車號前二位的取值*/

for(j=0;j<=9;j++)/*j:車號後二位的取值*/

if(i!=j)/*判斷二位數(shù)字是否相異*/

{

k=i*1000+i*100+j*10+j;/*計算出可能的整數(shù)*/

for(c=31;c*c<k;c++);/*判斷該數(shù)是否為另一整數(shù)的平方*/

if(c*c==k)printf("Lorry–No.is%d.\n",k);/*若是,打印結果*/

}

}

*運行結果

Lorry7744

13.該存多少錢

假設銀行一年整存零取的月息為%?,F(xiàn)在某人手中有一筆錢,他打算在今後的五年中的年底取出1000

元,到第五年時剛好取完,請算出他存錢時應存入多少。

*問題分析與算法設計

分析存錢和取錢的過程,可以採用倒推的方法。若第五年年底連本帶息要取1000元,則要先求出第五年年

初銀行存款的錢數(shù):

第五年初存款=1000/(1+12*

依次類推可以求出第四年、第三年……的年初銀行存款的錢數(shù):

第四年年初存款=(第五年年初存款+1000)/(1+12*

第三年年初存款=(第四年年初存款+1000)/(1+12*

第二年年初存款=(第三年年初存款+1000)/(1+12*

第一年年初存款=(第二年年初存款+1000)/(1+12*

通過以上過程就可以很容易地求出第一年年初要存入多少錢。

*程序說明與註釋

#include<>

intmain()

{

inti;

floattotal=0;

for(i=0;i<5;i++)/*i為年數(shù),取值為0~4年*/

total=(total+1000)/(1+*12);/*累計算出年初存款數(shù)額,第五次的計算

結果即為題解*/

printf("Hemustsave%.2fatfirst.\n",total);

}

*運行結果

Hemustsaveatfirst

14.怎樣存錢利最大

假設銀行整存整取存款不同期限的月息利率分別為:

%期限=1年

%期限=2年

%期限=3年

%期限=5年

%期限=8年

利息=本金*月息利率*12*存款年限。

現(xiàn)在某人手中有2000元錢,請通過計算選擇一種存錢方案,使得錢存入銀行20年後得到的利息最多(假定

銀行對超過存款期限的那一部分時間不付利息)。

*問題分析與算法設計

為了得到最多的利息,存入銀行的錢應在到期時馬上取出來,然後立刻將原來的本金和利息加起來再作為

新的本金存入銀行,這樣不斷地滾動直到滿20年為止,由於存款的利率不同,所以不同的存款方法(年限)

存20年得到的利息是不一樣的。

分析題意,設2000元存20年,其中1年存i1次,2年存i2次,3年存i3次,5年存i5次,8年存i8次,則到期

時存款人應得到的本利合計為:

2000*(1+rate1)i1*(1+rate2)i2*(1+rate3)i3*(1+rate5)i5*(1+rate8)i8

其中rateN為對應存款年限的利率。根據(jù)題意還可得到以下限制條件:

0<=i8<=2

0<=i5<=(20-8*i8)/5

0<=i3<=(20-8*i8-5*i5)/3

0<=i2<=(20-8*i8-5*i5-3*i3)/2

0<=i1=20-8*i8-5*i5-3*i3-2*i2

可以用窮舉法窮舉所有的i8、i5、i3、i2和i1的組合,代入求本利的公式計算出最大值,就是最佳存款方

案。

*程序說明與註釋

#include<>

#include<>

intmain()

{

inti8,i5,i3,i2,i1,n8,n5,n3,n2,n1;

floatmax=0,term;

for(i8=0;i8<3;i8++)/*窮舉所有可能的存款方式*/

for(i5=0;i5<=(20-8*i8)/5;i5++)

for(i3=0;i3<=(20-8*i8-5*i5)/3;i3++)

for(i2=0;i2<=(20-8*i8-5*i5-3*i3)/2;i2++)

{

i1=20-8*i8-5*i5-3*i3-2*i2;

term=*pow((double)(1+*12),(double)i1)

*pow((double)(1+2**12),(double)i2)

*pow((double)(1+3**12),(double)i3)

*pow((double)(1+5**12),(double)i5)

*pow((double)(1+8**12),(double)i8);

/*計算到期時的本利合計*/

if(term>max)

{

max=term;n1=i1;n2=i2;n3=i3;n5=i5;n8=i8;

}

}

printf("Formaxinumprofit,heshouldsosavehismoneyinabank:\n");

printf("madefixeddepositfor8year:%dtimes\n",n8);

printf("madefixeddepositfor5year:%dtimes\n",n5);

printf("madefixeddepositfor3year:%dtimes\n",n3);

printf("madefixeddepositfor2year:%dtimes\n",n2);

printf("madefixeddepositfor1year:%dtimes\n",n1);

printf("Toal:%.2f\n",max);

/*輸出存款方式*/

}

*運行結果

Formaxinumprofit,heshouldsosavehismoneyinabank:

madefixeddepositfor8year:0times

madefixeddepositfor5year:4times

madefixeddepositfor3year:0times

madefixeddepositfor2year:0times

madefixeddepositfor1year:0times

Total:

可見最佳的存款方案為連續(xù)四次存5年期。

*思考題

某單位對職工出售住房,每套為2萬元。買房付款的方法是:

一次交清,優(yōu)惠20%

從第一年開始,每年年初分期付款:

5年交清,優(yōu)惠50%;

10年交清,優(yōu)惠10%;

20年交清,沒有優(yōu)惠。

現(xiàn)在有人手中正好有2萬元,若假定在今後20年中物價和銀行利率均保持不變,問他應當選擇哪種付款方

式可以使應付的錢最少?

15.捕魚和分魚

A、B、C、D、E五個人在某天夜裡合夥去捕魚,到第二天凌晨時都疲憊不堪,於是各自找地方睡覺。日上

三桿,A第一個醒來,他將魚分為五份,把多餘的一條魚扔掉,拿走自己的一份。B第二個醒來,也將魚分

為五份,把多餘的一條魚扔掉,保持走自己的一份。C、D、E依次醒來,也按同樣的方法拿走魚。問他們

合夥至少捕了多少條魚?

*問題分析與算法設計

根據(jù)題意,總計將所有的魚進行了五次平均分配,每次分配時的策略是相同的,即扔掉一條魚後剩下的魚

正好分成五份,然後拿走自己的一份,餘下其它的四份。

假定魚的總數(shù)為X,則X可以按照題目的要求進行五次分配:X-1後可被5整除,餘下的魚為4*(X-1)、5。若

X滿足上述要求,則X就是題目的解。

*程序說明與註釋

#include<>

intmain()

{

intn,i,x,flag=1;/*flag:控制標記*/

for(n=6;flag;n++)/*採用試探的方法。令試探值n逐步加大*/

{

for(x=n,i=1&&flag;i<=5;i++)

if((x-1)%5==0)x=4*(x-1)/5;

elseflag=0;/*若不能分配則置標記falg=0退出分配過程*/

if(flag)break;/*若分配過程正常結束則找到結果退出試探的過程*/

elseflag=1;/*否則繼續(xù)試探下一個數(shù)*/

}

printf("Totalnumberoffishcatched=%d\n",n);/*輸出結果*/

}

*運行結果

Totalnumberoffishcatched=3121

*問題的進一步討論

程序採用試探法,試探的初值為6,每次試探的步長為1。這是過分保守的做法??梢栽谶M一步分析題目的

基礎上修改此值,增大試探的步長值,以減少試探次數(shù)。

*思考題

請使用其它的方法求解本題。

16.出售金魚

買賣提將養(yǎng)的一缸金魚分五次出售系統(tǒng)上一次賣出全部的一半加二分之一條;第二次賣出餘下的三分之一

加三分之一條;第三次賣出餘下的四分之一加四分之一條;第四次賣出餘下的五分之一加五分之一條;最

後賣出餘下的11條。問原來的魚缸中共有幾條金魚?

*問題分析與算法設計

題目中所有的魚是分五次出售的,每次賣出的策略相同;第j次賣剩下的(j+1)分之一再加1/(j+1)條。第

五次將第四次餘下的11條全賣了。

假定第j次魚的總數(shù)為X,則第j次留下:

x-(x+1)/(j+1)

當?shù)谒拇纬鍪弁戤厱r,應該剩下11條。若X滿足上述要求,則X就是題目的解。

應當注意的是:"(x+1)/(j+1)"應滿足整除條件。試探X的初值可以從23開始,試探的步長為2,因為X的值

一定為奇數(shù)。

*程序說明與註釋

#include<>

intmain()

{

inti,j,n=0,x;/*n為標誌變量*/

for(i=23;n==0;i+=2)/*控制試探的步長和過程*/

{

for(j=1,x=i;j<=4&&x>=11;j++)/*完成出售四次的操作*/

if((x+1)%(j+1)==0)/*若滿足整除條件則進行實際的出售操作*/

x-=(x+1)/(j+1);

else{x=0;break;}/*否則停止計算過程*/

if(j==5&&x==11)/*若第四次餘下11條則滿足題意*/

{

printf("Thereare%dfishesatfirst.\n",i);/*輸出結果*/

n=1;/*控制退出試探過程*/

}

}

}

*運行結果

Thereare59fishesatfirst.

*思考題

日本著名數(shù)學遊戲?qū)<抑写辶x作教授提出這樣一個問題:父親將2520個桔子分給六個兒子。分完後父親說

:「老大將分給你的桔子的1/8給老二;老二拿到後連同原先的桔子分1/7給老三;老三拿到後連同原先的

桔子分1/6給老四;老四拿到後連同原先的桔子分1/5給老五;老五拿到後連同原先的桔子分1/4給老六;

老六拿到後連同原先的桔子分1/3給老大」。結果大家手中的桔子正好一樣多。問六兄弟原來手中各有多

少桔子?

17.平分七筐魚

甲、乙、丙三位魚夫出海打魚,他們隨船帶了21只籮筐。當晚返航時,他們發(fā)現(xiàn)有七筐裝滿了魚,還有七

筐裝了半筐魚,另外七筐則是空的,由於他們沒有秤,只好通過目測認為七個滿筐魚的重量是相等的,7

個半筐魚的重量是相等的。在不將魚倒出來的前提下,怎樣將魚和筐平分為三份?

*問題分析與算法設計

根據(jù)題意可以知道:每個人應分得七個籮筐,其中有筐魚。採用一個3*3的數(shù)組a來表示三個人分到的

東西。其中每個人對應數(shù)組a的一行,數(shù)組的第0列放分到的魚的整筐數(shù),數(shù)組的第1列放分到的半筐數(shù),

數(shù)組的第2列放分到的空筐數(shù)。由題目可以推出:

。數(shù)組的每行或每列的元素之和都為7;

。對數(shù)組的行來說,滿筐數(shù)加半筐數(shù)=;

。每個人所得的滿筐數(shù)不能超過3筐;

。每個人都必須至少有1個半筐,且半筐數(shù)一定為奇數(shù)

對於找到的某種分魚方案,三個人誰拿哪一份都是相同的,為了避免出現(xiàn)重複的分配方案,可以規(guī)定:第

二個人的滿筐數(shù)等於第一個人的滿筐數(shù);第二個人的半筐數(shù)大於等於第一個人的半筐數(shù)。

*程序說明與註釋

#include<>

inta[3][3],count;

intmain()

{

inti,j,k,m,n,flag;

printf("Itexistspossibledistribtionplans:\n");

for(i=0;i<=3;i++)/*試探第一個人滿筐a[0][0]的值,滿筐數(shù)不能>3*/

{

a[0][0]=i;

for(j=i;j<=7-i&&j<=3;j++)/*試探第二個人滿筐a[1][0]的值,滿筐數(shù)不能>3*/

{

a[1][0]=j;

if((a[2][0]=7-j-a[0][0])>3)continue;/*第三個人滿筐數(shù)不能>3*/

if(a[2][0]<a[1][0])break;/*要求後一個人分的滿筐數(shù)>=前一個人,以排除重複情況*/

for(k=1;k<=5;k+=2)/*試探半筐a[0][1]的值,半筐數(shù)為奇數(shù)*/

{

a[0][1]=k;

for(m=1;m<7-k;m+=2)/*試探半筐a[1][1]的值,半筐數(shù)為奇數(shù)*/

{

a[1][1]=m;

a[2][1]=7-k-m;

for(flag=1,n=0;flag&&n<3;n++)

/*判斷每個人分到的魚是筐,flag為滿足題意的標記變量*/

if(a[n][0]+a[n][1]<7&&a[n][0]*2+a[n][1]==7)

a[n][2]=7-a[n][0]-a[n][1];/*計算應得到的空筐數(shù)量*/

elseflag=0;/*不符合題意則置標記為0*/

if(flag)

{

printf("No.%dFullbasketSemi–basketEmpty\n",++count);

for(n=0;n<3;n++)

printf("fisher%c:%d%d%d\n",

'A'+n,a[n][0],a[n][1],a[n][2]);

}

}

}

}

}

}

*運行結果

Itexistspossibledistributionplans:

FullbasketSemi–basketEmpty

fisherA:151

fisherB:313

fisherC:313

FullbasketSemi–basketEmpty

fisherA:232

fisherB:232

fisherC:313

*思考題

晏會上數(shù)學家出了一道難題:假定桌子上有三瓶啤酒,癬瓶子中的酒分給幾個人喝,但喝各瓶酒的人數(shù)是

不一樣的。不過其中有一個人喝了每一瓶中的酒,且加起來剛好是一瓶,請問喝這三瓶酒的各有多少人?

(答案:喝三瓶酒的人數(shù)分別是2人、3人和6人)

18.有限5位數(shù)

個位數(shù)為6且能被3整除的五位數(shù)共有多少?

*題目分析與算法設計

根據(jù)題意可知,滿足條件的五位數(shù)的選擇範圍是10006、10016。。。99996??稍O基礎數(shù)i=1000,通過計

算i*10+6即可得到欲選的數(shù)(i的變化範圍是1000~999),再判斷該數(shù)能否被3整除。

*程序說明與註釋

#include<>

intmain()

{

longinti;

intcount=0;/*count:統(tǒng)計滿足條件的五位數(shù)的個數(shù)*/

for(i=1000;i<9999;i++)

if(!((i*10+6)%3))/*判斷所選的數(shù)能否被3整除*/

count++;/*若滿足條件則計數(shù)*/

printf("count=%d\n",count);

}

*運行結果

count=2999

*思考題

求100到1000之間有多少個其數(shù)字之和為5的整數(shù)。

(答案:104,113,122,131,140,203,212,221,230,302,311,320,401,410,500)

除不盡的自然數(shù)

一個自然數(shù)被8除余1,所得的商被8除也余1,再將第二次的商被8除後余7,最後得到一個商為a。又知這

個自然數(shù)被17除余4,所得的商被17除余15,最後得到一個商是a的2倍。求這個自然數(shù)。

*問題分析與算法設計

根據(jù)題意,可設最後的商為i(i從0開始取值),用逆推法可以列出關係式:

(((i*8+7)*8)+1)*8+1=((2*i*17)+15)*18+4

再用試探法求出商i的值。

*程序說明與註釋

#include<>

intmain()

{

inti;

for(i=0;;i++)/*試探商的值*/

if(((i*8+7)*8+1)*8+1==(34*i+15)*17+4)

{/*逆推判斷所取得的當前i值是否滿足關係式*/

/*若滿足則輸出結果*/

printf("Therequirednumberis:%d\n",(34*i+15)*17+4);

break;/*退出循環(huán)*/

}

}

*運行結果

Therequirednumberis:1993

20.一個奇異的三位數(shù)

一個自然數(shù)的七進製表達式是一個三位數(shù),而這個自然數(shù)的九進製表示也是一個三位數(shù),且這兩個三位數(shù)

的數(shù)碼正好相反,求這個三位數(shù)。

*問題分析與算法設計

根據(jù)題意可知,七進制和九進製表示的這全自然數(shù)的每一位一定小於7,可設其七進制數(shù)形式為kji(i、j

、k的取值分別為1~6),然後設其九進製表示形式為ijk。

*程序說明與註釋

#include<>

intmain()

{

inti,j,k;

for(i=1;i<7;i++)

for(j=0;j<7;j++)

for(k=1;k<7;k++)

if(i*9*9+j*9+k==i+j*7+k*7*7)

{

printf("Thespecialnumberwith3digitsis:");

printf("%d%d%d(7)=%d%d%d(9)=%d(10)\n",k,j,i,i,j,k,i*9*9+j*9+k);

}

}

*運行結果

Thespecialnumberwith3digitsis:503(7)=305(9)=248(10)位反序數(shù)

設N是一個四位數(shù),它的9倍恰好是其反序數(shù),求N。反序數(shù)就是將整數(shù)的數(shù)字倒過來形成的整數(shù)。例如:

1234的反序數(shù)是4321。

*問題分析與算法設計

可設整數(shù)N的千、百、十、個位為i、j、k、l,其取值均為0~9,則滿足關係式:

(i*103+j*102+10*k+l)*9=(l*103+k*102+10*j+i)

的i、j、k、l即構成N。

*程序說明與註釋

#include<>

intmain()

{

inti;

for(i=1002;i<1111;i++)/*窮舉四位數(shù)可能的值*/

if(i%10*1000+i/10%10*100+i/100%10*10+i/1000==i*9)

/*判斷反序數(shù)是否是原整數(shù)的9倍*/

printf("Thenumbersatisfiedstatsconditionis:%d\n",i);

/*若是則輸出*/

}

*運行結果

Thenumbersatisfiedstatesconditionis:1089

22.求車速

一輛以固定速度行駛的汽車,司機在上午10點看到里程表上的讀數(shù)是一個對稱數(shù)(即這個數(shù)從左向右讀和

從右向左讀是完全一樣的),為95859。兩小時後里程表上出現(xiàn)了一個新的對稱數(shù)。問該車的速度是多少?

新的對稱數(shù)是多少?

*問題分析與算法設計

根據(jù)題意,設所求對稱數(shù)為i,其初值為95589,對其依次遞增取值,將i值的每一位分解後與其對稱位置

上的數(shù)進行比較,若每個對稱位置上的數(shù)皆相等,則可判定i即為所求的對稱數(shù)。

*程序說明與註釋

#include<>

intmain()

{

intt,a[5];/*數(shù)組a存放分解的數(shù)字位*/

longintk,i;

for(i=95860;;i++)/*以95860為初值,循環(huán)試探*/

{

for(t=0,k=100000;k>=10;t++)/*從高到低分解所取i值的每位數(shù)*/

{/*字,依次存放於a[0]~a[5]中*/

a[t]=(i%k)/(k/10);

k/=10;

}

if((a[0]==a[4])&&(a[1]==a[3]))

{

printf("Thenewsymmetricalnumberkelometersis:%d%d%d%d%d\n",

a[0],a[1],a[2],a[3],a[4]);

printf("Thevelocityofthecaris:%.2f\n",(i-95859)/;

break;

}

}

}

*運行結果

Thenewsymmetricalnumberkelometersis:95959.

Thevelocityofthecaris:

*思考題

將一個數(shù)的數(shù)碼倒過來所得到的新數(shù)叫原數(shù)的反序數(shù)。如果一個數(shù)等於它的反序數(shù),則稱它為對稱數(shù)。求

不超過1993的最大的二進制的對稱數(shù)。

23.由兩個平方三位數(shù)獲得三個平方二位數(shù)

已知兩個平方三位數(shù)abc和xyz,其中a、b、c、x、y、z未必是不同的;而ax、by、cz是三個平方二位數(shù)。

請編程求三位數(shù)abc和xyz。

*問題分析與算法設計

任取兩個平方三位數(shù)n和n1,將n從高向低分解為a、b、c,將n1從高到低分解為x、y、z。判斷ax、by、cz

是否均為完全平方數(shù)。

*程序說明與註釋

#include<>

#include<>

voidf(intn,float*s);

intmain()

{

inti,t;

floata[3],b[3];

print("Thepossibleperfectsquarescombinationsare:\n");

for(i=11;i<=31;++i)姆斯特朗數(shù)

如果一個正整數(shù)等於其各個數(shù)字的立方和,則稱該數(shù)為阿姆斯特朗數(shù)(亦稱為自戀性數(shù))。

如407=43+03+73就是一個阿姆斯特朗數(shù)。試編程求1000以內(nèi)的所有阿姆斯特朗數(shù)。

*問題分析與算法設計

可採用窮舉法,依次取1000以內(nèi)的各數(shù)(設為i),將i的各位數(shù)字分解後,據(jù)阿姆斯特朗數(shù)的性質(zhì)進行計算

和判斷。

*程序說明與註釋

#include<>

intmain()

{

inti,t,k,a[3];

printf("TherearefollwingArmstrongnumbersmallerthan1000:\n");

for(i=2;i<1000;i++)/*窮舉要判定的數(shù)i的取值範圍2~1000*/

{

for(t=0,k=1000;k>=10;t++)/*截取整數(shù)i的各位(從高向低位)*/

{

a[t]=(i%k)/(k/10);/*分別賦於a[0]~a[2}*/

k/=10;

}

if(a[0]*a[0]*a[0]+a[1]*a[1]*a[1]+a[2]*a[2]*a[2]==i)

/*判斷i是否為阿姆斯特朗數(shù)*/

printf("%5d",i);/*若滿足條件,則輸出*/

}

printf("\n");

}

*運行結果

TherearefollowingArmstrongnumbersmallerthan1000:

153370371407

25.完全數(shù)

如果一個數(shù)恰好等於它的因子之和,則稱該數(shù)為「完全數(shù)」。

*問題分析與算法設計

根據(jù)完全數(shù)的定義,先計算所選取的整數(shù)a(a的取值1~1000)的因子,將各因子累加於m,若m等於a,則可

確認a為完全數(shù)。

*程序說明與註釋

#include<>

intmain()

{

inta,i,m;

printf("Therearefollowingperfectnumberssmallerthan1000:\n");

for(a=1;a<1000;a++)/*循環(huán)控制選取1~1000中的各數(shù)進行判斷*/

{

for(m=0,i=1;i<=a/2;i++)/*計算a的因子,並將各因子之和m=a,則a是完全數(shù)輸出*/

if(!(a%i))m+=i;

if(m==a)

printf("%4d",a);

}

printf("\n");

}

*運行結果

TTherearefollowingperfectnumberssmallerthan1000:

628496

26.親密數(shù)

如果整數(shù)A的全部因子(包括1,不包括A本身)之和等於B;且整數(shù)B的全部因子(包括1,不包括B本身)之和

等於A,則將整數(shù)A和B稱為親密數(shù)。求3000以內(nèi)的全部親密數(shù)。

*問題分析與算法設計

按照親密數(shù)定義,要判斷數(shù)a是否有親密數(shù),只要計算出a的全部因子的累加和為b,再計算b的全部因子的

累加和為n,若n等於a則可判定a和b是親密數(shù)。計算數(shù)a的各因子的算法:

用a依次對i(i=1~a/2)進行模運算,若模運算結果等於0,則i為a的一個因子;否則i就不是a的因子。

*程序說明與註釋

#include<>

intmain()

{

inta,i,b,n;

printf("Therearefollowingfriendly–numberspairsmallerthan3000:\n");

for(a=1;a<3000;a++)/*窮舉1000以內(nèi)的全部整數(shù)*/

{

for(b=0,i=1;i<=a/2;i++)/*計算數(shù)a的各因子,各因子之和存放於b*/

if(!(a%i))b+=i;/*計算b的各因子,各因子之和存於n*/

for(n=0,i=1;i<=b/2;i++)

if(!(b%i))n+=i;

if(n==a&&a<b)

printf("%4d..%4d",a,b);/*若n=a,則a和b是一對親密數(shù),輸出*/

}

}

*運行結果

Therearefollowingfriendly–numberspairsmallerthan3000:

220..2841184..12102620..2924

27.自守數(shù)

自守數(shù)是指一個數(shù)的平方的尾數(shù)等於該數(shù)自身的自然數(shù)。例如:

252=625762=577693762=

請求出200000以內(nèi)的自守數(shù)

*問題分析與算法設計

若採用「求出一個數(shù)的平方後再截取最後相應位數(shù)」的方法顯然是不可取的,因為計算機無法表示過大的

整數(shù)。

分析手工方式下整數(shù)平方(乘法)的計算過程,以376為例:

376被乘數(shù)

X376乘數(shù)

———-

2256第一個部分積=被乘數(shù)*乘數(shù)的倒數(shù)第一位

2632第二個部分積=被乘數(shù)*乘數(shù)的倒數(shù)第二位

1128第三個部分積=被乘數(shù)*乘數(shù)的倒數(shù)第三位

———-

141376積

本問題所關心的是積的最後三位。分析產(chǎn)生積的後三位的過程,可以看出,在每一次的部分積中,並不是

它的每一位都會對積的後三位產(chǎn)生影響??偨Y規(guī)律可以得到:在三位數(shù)乘法中,對積的後三位產(chǎn)生影響的

部分積分別為:

第一個部分積中:被乘數(shù)最後三位*乘數(shù)的倒數(shù)第一位

第二個部分積中:被乘數(shù)最後二位*乘數(shù)的倒數(shù)第二位

第三個部分積中:被乘數(shù)最後一位*乘數(shù)的倒數(shù)第三位

將以上的部分積的後三位求和後截取後三位就是三位數(shù)乘積的後三位。這樣的規(guī)律可以推廣到同樣問題的

不同位數(shù)乘積。

按照手工計算的過程可以設計算法編寫程序。

*程序說明與註釋

#include<>

intmain()

{

longmul,number,k,ll,kk;

printf("Itexistsfollowingautomorphicnmberssmallthan200000:\n");

for(number=0;number<200000;number++)

{

for(mul=number,k=1;(mul/=10)>0;k*=10);

/*由number的位數(shù)確定截取數(shù)字進行乘法時的係數(shù)k*/

kk=k*10;/*kk為截取部分積時的係數(shù)*/

mul=0;/*積的最後n位*/

ll=10;/*ll為截取乘數(shù)相應位時的係數(shù)*/

while(k>0)

{

mul=(mul+(number%(k*10))*(number%ll-number%(ll/10)))%kk;

/*(部分積+截取被乘數(shù)的後N位*截取乘數(shù)的第M位),%kk再截取部分積*/

k/=10;/*k為截取被乘數(shù)時的係數(shù)*/

ll*=10;

}

if(number==mul)/*判斷若為自守數(shù)則輸出*/

printf("%ld",number);

}

}

*運行結果

Itexstsfollowingautomorphicnumbnerssmallerthan200000:

01562576376625937690625109376

28.回文數(shù)

打印所有不超過n(取n<256)的其平方具有對稱性質(zhì)的數(shù)(也稱回文數(shù))。

*問題分析與算法設計

對於要判斷的數(shù)n,計算出其平方後(存於a),將a的每一位進行分解,再按a的從低到高的順序?qū)⑵浠謴统?/p>

一個數(shù)k(如n=13,則a=169且k=961),若a等於k則可判定n為回亠數(shù)。

*程序說明與註釋

原程序好像有錯,而且比較費解,現(xiàn)基於原程序修改如下(如果讀者還發(fā)現(xiàn)錯誤請?zhí)岢觯?/p>

#include<>

intmain(void)

{

intm[16],n,i,t,count=0;

longunsigneda,k;

printf("No.numberit'ssquare(palindrome)\n");

for(n=1;n<256;n++)/*窮舉n的取值範圍*/

{

k=0;t=1;a=n*n;/*計算n的平方*/

for(i=0;a!=0;i++)/*從低到高分解數(shù)a的每一位存於數(shù)組m[0]~m[16]*/

{

m=a%10;numberit'ssquare(palindrome)

111

224

339

411121

522484

626676

710110201

811112321

912114641

1020240804

1121244944

numberit'ssquare(palindrome)\n");

for(n=1;n<256;n++)/*窮舉n的取值範圍*/

{

k=0;t=1;a=n*n;/*計算n的平方*/

for(i=1;a!=0;i++)/*從低到高分解數(shù)a的每一位存於數(shù)組m[1]~m[16]*/

{

m=a%10;numberit'ssquare(palindrome)

111

224

339

411121

522484

626676

710110201

811112321

912114641

29.求具有abcd=(ab+cd)2性質(zhì)的四位數(shù)

3025這個數(shù)具有一種獨特的性質(zhì):將它平分為二段,即30和25,使之相加後求平方,即(30+25)2,恰好等

於3025本身。請求出具有這樣性質(zhì)的全部四位數(shù)。

*問題分析與算法設計

具有這種性質(zhì)的四位數(shù)沒有分佈規(guī)律,可以採用窮舉法,對所有四位數(shù)進行判斷,從而篩選出符合這種性

質(zhì)的四位數(shù)。具體算法實現(xiàn),可任取一個四位數(shù),將其截為兩部分,前兩位為a,後兩位為b,然後套用公

式計算並判斷。

*程序說明與註釋

#include<>

intmain()

{

intn,a,b;

printf("Therearefollowingnumberwith4digitssatisfiedcondition\n");

for(n=1000;n<10000;n++)/*四位數(shù)N的取值範圍1000~9999*/

{

a=n/100;/*截取N的前兩位數(shù)存於a*/

b=n%100;/*截取N的後兩位存於b*/

if((a+b)*(a+b)==n)/*判斷N是否為符合題目所規(guī)定的性質(zhì)的四位數(shù)*/

printf("%d",n);

}

}

*運行結果

Therearefollowingnumberswith4digitssatisfiedcondition:

202530259801

30.求素數(shù)

求素數(shù)表中1~1000之間的所有素數(shù)

*問題分析與算法設計

素數(shù)就是僅能衩1和它自身整除的整數(shù)。判定一個整數(shù)n是否為素數(shù)就是要判定整數(shù)n能否被除1和它自身之

外的任意整數(shù)整除,若都不能整除,則n為素數(shù)。

程序設計時i可以從2開始,到該整數(shù)n的1/2為止,用i依次去除需要判定的整數(shù),只要存在可以整除該數(shù)

的情況,即可確定要判斷的整數(shù)不是素數(shù),否則是素數(shù)。

*程序說明與註釋

#include<>

intmain()

{

intn1,nm,i,j,flag,count=0;

do{

printf("InputSTARTandEND=");

scanf("%d%d",&n1,&nm);/*輸入求素數(shù)的範圍*/

}while(!(n1>0&&n1<nm));/*輸入正確的範圍*/

printf("………..PRIMETABLE(%d–%d)…………\n",n1,nm);

if(n1==1||n1==2)/*處理素數(shù)2*/

{

printf("%4d",2);

n1=3;count++;

}

for(i=n1;i<=nm;i++)/*判定指定範圍內(nèi)的整數(shù)是否為素數(shù)*/

{

if(!(i%2))continue;

for(flag=1,j=3;flag&&j<i/2;j+=2)

/*判定能否被從3到整數(shù)的一半中的某一數(shù)所整除*/

if(!(i%j))flag=0;/*若能整除則不是素數(shù)*/

if(flag)printf(++count%15"%4d":"%4d\n",i);

}

}

*思考題

請找出十個最小的連續(xù)自然數(shù),它們個個都是合數(shù)(非素數(shù))31.歌德巴赫猜想

驗證:2000以內(nèi)的正偶數(shù)都能夠分解為兩個素數(shù)之和(即驗證歌德巴赫猜想對2000以內(nèi)的正偶數(shù)成立)。

*問題分析與算法設計

為了驗證歌德巴赫猜想對2000以內(nèi)的正偶數(shù)都是成立的,要將整數(shù)分解為兩部分,然後判斷出分解出的兩

個整數(shù)是否均為素數(shù)。若是,則滿足題意;否則重新進行分解和判斷。

程序中對判斷是否為素數(shù)的算法進行了改進,對整數(shù)判斷「用從2開始到該整數(shù)的一半」改為「2開始到該

整數(shù)的平方根」。原因何在請自行分析。

*程序說明與註釋

#include<>

#include<>

intfflag(intn);

intmain()

{

inti,n;

for(i=4;i<=2000;i+=2)

{

for(n=2;n<i;n++)/*將偶數(shù)i分解為兩個整數(shù)*/

if(fflag(n))/*分別判斷兩個整數(shù)是否均為素數(shù)*/

if(fflag(i-n))

{

printf("%14d=%d+%d\n",i,n,i-n);/*若均是素數(shù)則輸出*/

break;

}

if(n==i)printf("error%d\n",i);

}

}

intfflag(inti)/*判斷是否為素數(shù)*/

{

intj;

if(i<=1)return0;

if(i==2)return1;

if(!(i%2))return0;/*ifno,return0*/

for(j=3;j<=(int)(sqrt((double)i)+1);j+=2)

if(!(i%j))return0;

return1;/*ifyes,return1*/

}

32.可逆素數(shù)

求四位的可逆素數(shù)??赡嫠財?shù)指:一個素數(shù)將其各位數(shù)字的順序倒過來構成的反序數(shù)也是素數(shù)。

*問題分析與算法設計

本題的重點不是判斷素數(shù)的方法,而是求一個整數(shù)的反序數(shù)。求反序數(shù)的方法是從整數(shù)的末尾依次截

取最後一位數(shù)字,每截取一次後整數(shù)縮小10倍,將截取的數(shù)字作為新的整數(shù)的最後一位(新的整數(shù)擴大10

倍後加上被截取的數(shù)字)。這樣原來的整數(shù)的數(shù)字從低到高被不斷地截取,依次作為新的整數(shù)從高到低的

各位數(shù)字。

*程序說明與註釋

#include<>

#include<>

intnum(intnumber);

intok(intnumber);

intmain()

{

inti,count;

printf("Thereareinvertableprimeswith4digits:\n");

for(count=0,i=1001;i<9999;i+=2)文素數(shù)

求不超過1000的回文素數(shù)。

*問題分析與算法設計

所謂回文素數(shù)是指,對一個整數(shù)n從左向右和從由向左讀其結果值相同且是素數(shù),即稱n為回文素數(shù)。

所以本題的重點不是判斷素數(shù)的方法,而是求回文整數(shù)。構造回文數(shù)的方法很多,這裡僅介紹一種最簡單

的算法。實現(xiàn)思路是先求出一個整數(shù)的回文數(shù),再判斷是否為素數(shù)。

不超過1000的回文數(shù)包括二位和三位的回文數(shù),我們採用窮舉法來構造一個整數(shù)並求與其對應的反序

數(shù),若整數(shù)與其反序數(shù)相等,則該整數(shù)是回文數(shù)。

*程序說明與註釋

#include<>

inta(intn)

intmain()

{

inti,j,t,k,s;

printf("Followingarepalindromeprimesnotgreaterthan1000:\n");

for(i=0;i<=9;++i)發(fā)就發(fā)

「1898–要發(fā)就發(fā)」。請將不超過1993的所有素數(shù)從小到大排成第一行,第二行上的每個素數(shù)都等於它右

肩上的素數(shù)之差。編程求出:第二行數(shù)中是否存在這樣的若干個連續(xù)的整數(shù),它們的和恰好是1898假好

存在的話,又有幾種這樣的情況?

第一行:2357111317……197919871993

第二行:122424……86

*問題分析與算法設計

首先從數(shù)學上分析該問題:

假設第一行中的素數(shù)為n[1]、n[2]、n[3]….n、…第二行中的差值為m[1]、m[2]、m[3]…m[j]…。其

中m[j]為:

m[j]=n[j+1]-n[j]。

則第二行連續(xù)N個數(shù)的和為:

SUM=m[1]+m[2]+m[3]+…+m[j]

=(n[2]-n[1])+(n[3]-n[2])+(n[4]-n[3])+…+(n[j+1]-n[j])

=n[j+1]-n[1]

由此題目就變成了:在不超過1993的所有素數(shù)中是否存在這樣兩個素數(shù),它們的差恰好是1898。若存在,

則第二行中必有所需整數(shù)序列,其和恰為1898,。

對等價問題的求解是比較簡單的。

由分析可知,在素數(shù)序列中不必包含2,因為任意素數(shù)與2的差一定為奇數(shù),所以不必考慮。

*程序與程序註釋:

#include<>

#include<>

#defineNUM320

intnumber[NUM];/*存放不超過1993的全部奇數(shù)*/

intfflag(inti);

intmain()

{

inti,j,count=0;

printf("therearefollwingprimessequencesinfirstrow:\n");

for(j=0,i=3;i<=1993;i+=2)/*求出不超過1993的全部奇數(shù)*/

if(fflag(i))number[j++]=i;

for(j–;number[j]>1898;j–)/*從最大的素數(shù)開始向1898搜索*/

{

for(i=0;number[j]-number>1898;i++);/*循環(huán)查找滿足條件的素數(shù)*/

if(number[j]-number==1898)/*若兩個素數(shù)的差為1898,則輸出*/

printf("(%d).

溫馨提示

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

評論

0/150

提交評論