C語言趣味編程百例精解_第1頁
C語言趣味編程百例精解_第2頁
C語言趣味編程百例精解_第3頁
C語言趣味編程百例精解_第4頁
已閱讀5頁,還剩157頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

C/C++語言經典、實用、趣味程序設計編程百例精解TOC\o"1-5"\h\z\o"CurrentDocument"最簡單的問題與算法 5\o"CurrentDocument"繪制余弦曲線 5\o"CurrentDocument"繪制余弦曲線和直線 6\o"CurrentDocument"繪制圓 7\o"CurrentDocument"歌星大獎賽 8\o"CurrentDocument"求最大數 9\o"CurrentDocument"高次方數的尾數 10\o"CurrentDocument"階乘尾數零的個數 11\o"CurrentDocument"借書方案知多少 12\o"CurrentDocument"楊輝三角形 13\o"CurrentDocument"數制轉換 15\o"CurrentDocument"生活中的數學問題 17\o"CurrentDocument"打魚還是曬網 17\o"CurrentDocument"抓交通肇事犯 19\o"CurrentDocument"該存多少錢 20\o"CurrentDocument"怎樣存錢利最大 21\o"CurrentDocument"捕魚和分魚 23\o"CurrentDocument"出售金魚 24\o"CurrentDocument"平分七筐魚 25\o"CurrentDocument"整數趣題 27\o"CurrentDocument"有限5位數 27\o"CurrentDocument"8除不盡的自然數 28\o"CurrentDocument"ー個奇異的三位數 29\o"CurrentDocument"4位反序數 30\o"CurrentDocument"求車速 31\o"CurrentDocument"由兩個平方三位數獲得三個平方二位數 32\o"CurrentDocument"阿姆斯特朗數 34\o"CurrentDocument"完全數 35\o"CurrentDocument"親密數 36\o"CurrentDocument"自守數 37\o"CurrentDocument"回文數 39\o"CurrentDocument"求具有abcd=(ab+cd)2性質的四位數 42\o"CurrentDocument"素數的家族 43\o"CurrentDocument"求素數 43\o"CurrentDocument"歌德巴赫猜想 44\o"CurrentDocument"可逆素數 45\o"CurrentDocument"回文素數 47\o"CurrentDocument"要發就發 49\o"CurrentDocument"素數幻方 51\o"CurrentDocument"不定方程求整數解 57\o"CurrentDocument"小明買書 125\o"CurrentDocument"波松瓦酒的分酒趣題 127\o"CurrentDocument"定理與猜想 129\o"CurrentDocument"求兀的近似值(2) 131\o"CurrentDocument"奇數平方的ー個有趣性質 132\o"CurrentDocument"角谷猜想 133\o"CurrentDocument"四方定理 134\o"CurrentDocument"卡布列克常數 135\o"CurrentDocument"尼科徹斯定理 137\o"CurrentDocument"回文數的形成 139\o"CurrentDocument"智力游戲 141\o"CurrentDocument"自動發牌 141\o"CurrentDocument"黑白子交換 143\o"CurrentDocument"常勝將軍 146\o"CurrentDocument"搶30 147\o"CurrentDocument"搬山游戲 149\o"CurrentDocument"人機猜數游戲 151\o"CurrentDocument"人機猜數游戲(2) 153\o"CurrentDocument"漢諾塔 156\o"CurrentDocument"其他趣味程序 158\o"CurrentDocument"兎子產子 158\o"CurrentDocument"將阿拉伯數字轉換為羅馬數字 160\o"CurrentDocument"選美比賽 162\o"CurrentDocument"滿足特異條件的數歹!! 164\o"CurrentDocument"ハ皇后問題 166數字移動……' 172最簡單的問題與算法繪制余弦曲線在屏幕上用、'*”顯示0-360度的余弦函數cos(x)曲線問題分析與算法設計如果在程序屮使用數組,這個問題十分簡單。但若規定不能使用數組,問題就變得不容易了。關鍵在于余弦曲線在〇?360度的區間內,一行中要顯示兩個點,而對一般的顯示器來說,只能按行輸出,即:輸出第一行信息后,只能向下一行輸出,不能再返回到上一行。為了獲得本文要求的圖形就必須在一行中一次輸出兩個''*"。為了同時得到余弦函數cos(x)闇形在一行上的兩個點,考慮利用cos(x)的左右対稱性。將屏幕的行方向定義為X,列方向定義為y,則0~180度的圖形與180-360度的圖形是左右對稱的,若定義闇形的總寬度為62歹リ,計算出x行0-180度時y點的坐標m,那么在同一行與之對稱的180-360度的y點的坐標就應為62-m。程序中利用反余弦函數acos計算坐標(x,y)的對應關系。使用這種方法編出的程序短小精煉,體現了一定的技巧。程序說明與注釋#include<stdio.h>#include<math.h>intmain()<doubley;intx,m;for(y=l;y>=-l;y-=0.1)/*y為列方向,值從1至b1,步長為0.1*/<m=acos(y)*10;/?計算出y對應的弧度m,乘以10為圖形放大倍數?/for(x=l;x<m;x++)printf("");printf("*");/*控制打印左側的?號?/for(;x<62-m;x++)printf("");printf("*\n");/?控制打印同一行中對稱的右側?號?/}return0;}思考題如何實現用、'*"顯示0-360度的sin(x)曲線.繪制余弦曲線和直線在屏幕上顯示0~360度的cos(x)曲線與直線f(x)=45*(y-l)+31的迭加闇形。其中cos(x)圖形用、'*”表示,f(x)用''+"表示,在兩個圖形相交的點上則用f(x)圖形的符號。?問題分析與算法設計本題可以在上題的基礎上進行修改。圖形迭加的關鍵是要在分別計算出同?行中兩個圖形的列方向點坐標后,正確判斷相互的位置關系。為此,可以先判斷圖形的交點,再分別控制打印兩個不同的圖形。?程序注釋與說明#include<stdio.h>#include<math.h>intmain(){doubley;intx,m,n,yy;for(yy=0;yy<=20;yy++)/?對于第一個y坐標進行計算并在一行中打印圖形?/{y=0.1*yy;/*y!屏幕行方向坐標?/m=acos(l-y)*10;/*m:cos(x)曲線上y點對應的屏幕列坐標?/n=45*(y-l)+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;}?思考題如何實現sin(x)曲線與cos(x)曲線圖形的同時顯示。繪制圓在屏幕上用''*'’畫一個空心的圓問題分析與算法設計打印圓可利用圖形的左右對稱性。根據圓的方程:R*R=X*X+Y?丫可以算出圓上每一點行和列的對應關系。程序說明與注釋#include<stdio.h>#include<math.h>intmain(){doubley;intx,m;for(y=10;y>=-10;y-)<m=2.5*sqrt(100-y*y);/*計算行y對應的列坐標m,2.5是屏幕縱橫比調節系數因為屏幕的行距大于列距,不進行調行顯示出來的將是橢圓?/for(x=l;x<30-m;x++)printf("");/?圖形左側空白控制?/printf("*");/*圓的左側?/for(;x<30+m;x++)printf("");/?圖形的空心部分控制?/printf("*\n");/?圓的右側?/)return0;)思考題實現函數y=x2的圖形與圓的圖形疊加顯示歌星大獎賽在歌星大獎賽中,有10個評委為參賽的選手打分,分數為1?100分。選手最后得分為:去掉ー個最高分和一個最低分后其余8個分數的平均值。請編寫ー個程序實現。?問題分析與算法設計這個問題的算法十分簡單,但是要注意在程序中判斷最大、最小值的變量是如何賦值的。?程序說明與注釋#include<stdio.h>intmain()intinteger),max,min,sum;max=-32768;/?先假設當前的最大值max為C語言整型數的最小值?/min=32767;/?先假設當前的最小值min為C語言整型數的最大值?/sum=0;/*將求累加和變量的初值置為0?/for(i=l;i<=10;i++){printf("Inputnumber%d=n,i);scanf("%d",&integer);/*輸入評委的評分?/sum+=integer;/?計算總分?/if(integer>max)max=integer;/?通過比較篩選出其中的最高分?/if(integervmin)min=integer;/?通過比較篩選出其中的最低分?/}printf("Canceledmaxscore:%d\nCanceledminscore:%d\n",max,min);printf("Averagescore:%d\n",(sum-max-min)/8);/?輸出結果?/}?運行結果Inputnumberl=90Inputnumber2=91Inputnumber3=93Inputnumber4=94Inputnumber5=90Inputnumber6=99Inputnumber7=97Inputnumber8=92Inputnumber9=91Inputnumberl0=95Canceledmaxscore:99Canceledminscore:90Averagescore:92.思考題題目條件不變,但考慮同時對評委評分進行裁判,即在10個評委中找出最公平(即評分最接返平均分)和最不公平(即與平均分的差距最大)的評委,程序應該怎樣實現?求最大數問555555的約數中最大的三位數是多少?問題分析與算法設計根據約數的定義,對于ー個整數N,除去1和它自身外,凡能整除N的數即為N的約數。因此,最簡單的方法是用2到N-1之間的所有數去除N,即可求出N的全部約數。本題只要求取約數中最大的三位數,則其取值范圍可限制在100到999之間。程序說明與注釋#include<stdio.h>intmain()<longi;intj;printf("Pleaseinputnumber:");scanf("%ld",&i);for(j=999;j>=100;j-)if(i%j==O){printf("Themaxfactorwith3digitsin%ldis:%d,\n",i,j);break;}}運行結果輸入:555555輸出:Themaxfactorwith3digitsin555555is:777高次方數的尾數求13的13次方的最后三位數問題分析與算法設計解本題最直接的方法是:將13累乘13次方截取最后三位即可。但是由于計算機所能表示的整數范圍有限,用這種、'正確"的算法不可能得到正確的結果。事實上,題冃僅要求最后三位的值,完全沒有必要求13的13次方的完整結果。研究乘法的規律發現:乘積的最后三位的值只與乘數和被乘數的后三位有關,與乘數和被乘數的高位無關。利用這ー規律,可以大大簡化程序。?程序說明與注釋#include<stdio.h>intmain(){inti,x,y/ast=l;/?變量last保存求X的丫次方過程中的部分乘積的后三位?/printf("InputXand丫(X**Y):");scanf("%d**%d",&x,&y);for(i=l;i<=y;i++)/*X自乘丫次?/last=last*x%100〇;/?將!ast乘X后對1000取模,即求積的后三位?/printf("Thelast3digitsof%d**%dis:%d\n",x,y,last%1000);/?打印結果?/}*運行結果InputXand丫(X**Y):13**13Thelast3digitsof13**13is:253InputXandY(X**Y):13**20Thelast3digitsof13**20is:801階乘尾數零的個數100!的尾數有多少個零??問題分析與算法設計可以設想:先求出100!的值,然后數一下末尾有多少個零。事實上,與上題ー樣,由于計算機所能表示的整數范圍有限,這是不可能的。為了解決這個問題,必須首先從數學上分析在100!結果值的末尾產生零的條件。不難看出:ー個整數若含有一個因子5,則必然會在求100!時產生一個零。因此問題轉化為求1到100這100個整數中包含了多少個因子5。若整數N能被25整除,則N包含2個因子5:若整數N能被5整除,則N包含1個因子5。?程序說明與注釋#include<stdio.h>intmain(){inta,count=0;for(a=5;av=100;a+=5)〃循環從5開始,以5的倍數為步長,考察整數{++count;〃若為5的倍數,計數器加1if(!(a%25))++count;〃若為25的倍數,計數器再加1}printf("Thenumberof0intheendof100!is:%d.\n",count);〃打印結果return0;}*運行結果Thenumberof0intheendof100!is:24.?問題進ー步討論本題的求解程序是正確的,但是存在明顯的缺點。程序中判斷整數N包含多少個因子5的方法是與程序中的100有關的,若題目中的100改為1000,則就要修改程序中求因子5的數目的算法了.?思考題修改程序中求因子5的數目的算法,使程序可以求出任意N!的末尾有多少個零。借書方案知多少小明有五本新書,要借給A,B,C三位小朋友,若每人每次只能借一本,則可以有多少種不同的借法??問題分析與算法設計本問題實際上是ー個排列問題,即求從5個中取3個進行排列的方法的總數。首先對五本書從1至5進行編號,然后使用窮舉的方法。假設三個人分別借這五本書中的一本,當三個人所借的書的編號都不相同時,就是滿足題意的?種借閱方法。?程序說明與注釋intmain(){intazbzczcount=0;printf("TherearediffrentmethodsforXMtodistributebooksto3readers:\nH);for(a=l;av=5;a++)/?窮舉第一個人借5本書中的1本的全部情況?/for(b=l;bv=5;b++)/*窮舉第二個人借5本書中的一本的全部情況?/for(c=l;a!=b&&cv=5;c++)/*當前兩個人借不同的書時,窮舉第三個人借5本書中的1本的全部情況?/if(c!=a&&c!=b)/*判斷第三人與前兩個人借的書是否不同?/printf(count%8?"%2d:%dz%dz%d":"%2d:%dz%dz%d\n"z+4-countzazbzc);/?打印可能的借閱方法?/}?運行結果TherearediffrentmethodsforXMtodistributebooksto3readers:1:1,2,32:1,2,43:1,2,54:1,3,25:1,3,46:1,3,57:1,4,28:1,4,39:1,4,510:1,5,211:1,5,312:1,5,413:2,1,314:2,1,415:2,1,516:2,3,117:2,3,418:2,3,519:2,4,120:2,4,321:2,4,522:2,5,123:2,5,324:2,5,425:3,1,226:3,1,427:3,1,528:3,2,129:3,2,430:3,2,531:3,4,132:3,4,233:3,4,534:3,5,135:3,5,236:3,5,437:4,1,238:4,1,339:4,1,540:4,2,141:4,2,342:4,2,543:4Z3,144:4,3,245:4,3,546:4,5,147:4,5,248:4,5,349:5,1,250:5,1,351:5,1,452:5,2,153:5,2,354:5,2,455:5,3,156:5,3,257:5,3,458:5,4,159:5,4,260:5z4,3楊輝三角形在屏幕上顯示楊輝三角形11112113311464115101051?問題分析與算法設計楊輝三角形中的數,正是(x+y)的N次方暴展開式各項的系數。本題作為程序設計中具有代表性的題目,求解的方法很多,這里僅給出ー種。從楊輝三角形的特點出發,可以總結出:1)第N行有N+1個值(設起始行為第0行)2)對于第N行的第J個值:(N>=2)當〕=1或J=N+1時:其值為1J!=l且J!=N+1時:其值為第N-1行的第J-!個值與第N-1行第J個值之和將這些特點提煉成數學公式可表示為:1x=l或x=N+lc(x,y)=c(x-l,y-l)+c(x-l,y)其它本程序應是根據以上遞歸的數學表達式編制的。?程序說明與注釋#include<stdio.h>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=l;j<i+2;j++)printf("%4d",c(i,j));/?輸出第i行的第j個值?/printf("\n");}}voidintc(intx,inty)/?求楊輝三角形中第x行第y列的值?/intz;?f((y==l)ll(y==x+l))return1;/?若為x行的第1或第x+1歹リ,則輸出1ツz=c(x?l,y?l)+c(x?l,y);/?否則,其值為前一行中第y-1列與第y列值之和*/returnz;)?思考題自行設計ー種實現楊輝三角形的方法數制轉換將任一整數轉換為二進制形式?問題分析與算法設計將十進制整數轉換為二進制的方法很多,這里介紹的實現方法利用了C語言能夠對位進行操作的特點。對于C語言來說,一?個整數在計算機內就是以二進制的形式存儲的,所以沒有必要再將一個整數經過ー系列的運算轉換為二進制形式,只要將整數在內存中的二進制表示輸出即可。?程序說明與注釋#include<stdio.h>voidprintb(intzint);intmain(){intx;printf("Inputnumber:'1);scanf("%d'\&x);printf("numberofdecimalform:%d\n"zx);printf("it'sbinaryform:");printb(x,sizeof(int)*8);/*x:整數sizeof(int):int型在內存中所占的字節數sizeof(int)*8:int型對應的位數?/putchar('\n');}voidprintb(intx,intn){if(n>0){putchar('O'+((unsigned)(x&(lvv(n?l)))>>(n-l)));/?輸出第n位?/printb(x,n?l);/?歸調用,輸出x的后n-!位?/}}?運行結果輸入:8輸出:numberofdecimalform:8it'sbunaryform:0000000000001000輸入:?8輸出:numberofdecimalform:-8it'sbinaryform:1111111111111000輸入:32767輸出:numberofdecimalform:32767it'sbinaryform:0111111111111111輸入:-32768輸出:numberofdecimalform:-32768it'sbinaryform:1000000000000000輸入:128輸出:numberofdecimalform:128it'sbinaryform:0000000010000000問題的進ー步討論充分利用C語言可以對位進行操作的特點,可以編寫許多其它高級語言不便于編寫甚至根本無法編寫的程序。位操作是c語言的一大特點,在深入學習c語言的過程中應カ求很好掌握。程序中使用的位運算方法不是最佳的,也可以不用遞歸操作,大家可以自行對程序進行優化。思考題將任意正整數轉換為四進制或ハ進制數生活中的數學問題打魚還是曬網中國有句俗語叫、、三天打魚兩天曬網’某人從1990年1月1日起開始''三天打魚兩天曬網”,問這個人在以后的某ー天中是''打魚’‘還是"曬網'問題分析與算法設計根據題意可以將解題過程分為三步:1)計算從1990年1月1日開始至指定日期共有多少天;2)由于'、打魚"和''曬網"的周期為5天,所以將計算出的天數用5去除;3)根據余數判斷他是在、、打魚"還是在"曬網";若余數為1,2,3,則他是在''打魚"否則是在"曬網"在這三步中,關鍵是第一步。求從1990年1月1日至指定日期有多少天,要判斷經歷年份中是否有閏年,二月為29天,平年為28天。閏年的方法可以用偽語句描述如下:如果((年能被4除盡且不能被100除盡)或能被400除盡)則該年是閏年;否則不是閏年。C語言中判斷能否整除可以使用求余運算(即求模)程序說明與注釋#include<stdio.h>intdays(structdateday);structdate{intyear;intmonth;intday;};intmain(){structdatetoday,term;intyearday,year,day;printf("Enteryear/month/day:");scanf("%d%d%d”,&today.year,&today.month,&today.day);/?輸入日期?/term.month=12;/*設置變量的初始值;月?/term.day=31;/*設置變量的初始值:日?/for(yearday=0,year=1990;year<today.year;year++)<term.year=year;yearday+=days(term);/?計算從1990年至指定年的前一年共有多少天?/}yearday+=days(today);/?カ口上指定年中至リ指定口期的天數?/day=yearday%5;/?求余數?/if(day>0&&day<4)printf(”hewasfishingatthatday.\n");/?打印結果?/elseprintf(nHewassleepingatthatday.、n”);}intdays(structdateday){staticintday_tab[2][13]={{〇,31,28,31,30,31,30,31,31,30,31,30,31,},/*平均每月的天數?/{0,31,29,31,30,31,30,31,31,30,31,30,31,},};inti,lp;lp=day.year%4==0&&day.year%100!=0||day.year%400==0;/?判定year為閏年還是平年,lp=o為平年,非〇為閏年?/for(i=l;ivday.month;i++)/?計算本年中自1月1日起的天數?/day.day+=day_tab[lp][i];returnday.day;??運行結果Enteryear/month/day:19911025Hewasfishingatday.Enteryear/month/day:19921025Hewassleepingatday.Enteryear/month/day:19931025Hewassleepingatday.?思考題請打印出任意年份的日歷抓交通肇事犯ー輛卡車違反交通規則,撞人后逃跑。現場有三人目擊事件,但都沒有記住車號,只記下車號的ー些特征。甲說:牌照的前兩位數字是相同的:乙說:牌照的后兩位數字是相同的,但與前兩位不同;丙是數學家,他說:四位的車號剛好是ー個整數的平方。請根據以上線索求出車號。問題分析與算法設計按照題目的要求造出ー個前兩位數相同、后兩位數相同且相互間又不同的整數,然后判斷該整數是否是另一個整數的平方。程序說明與注釋#include<stdio.h>#include<math.h>intmain(){inti,j,k,c;for(i=l;i<=9;i++)/*i:車號前二位的取值?/for(j=0;j<=9;j++)/*j:車號后二位的取值?/if(i!=j)/?判斷二位數字是否相異?/{k=i*1000+i*100+j*10+j;/?計算出可能的整數?/for(c=31;c*c<k;c++);/?判斷該數是否為另一整數的平方?/if(c*c==k)printf("Lorry-No.is%d.\n",k);/?若是,打印結果?/)}運行結果Lorry_No.is7744該存多少錢假設銀行一年整存零取的月息為0.63%。現在某人手中有一筆錢,他打算在今后的五年中的年底取出1000元,到第五年時剛好取完,請算出他存錢時應存入多少。問題分析與算法設計分析存錢和取錢的過程,可以采用倒推的方法。若第五年年底連本帶息要取1000元,則要先求出第五年年初銀行存款的錢數:第五年初存款=1000/(1+12*0.0063)依次類推可以求出第四年、第三年的年初銀行存款的錢數:第四年年初存款=(第五年年初存款+1000)/(1+12*0.0063)第三年年初存款=(第四年年初存款+1000)/(1+12*0.0063)第二年年初存款=(第三年年初存款+1000)/(1+12*0.0063)第一年年初存款=(第二年年初存款+1000)/(1+12*0.0063)通過以上過程就可以很容易地求出第一年年初要存入多少錢.程序說明與注釋#include<stdio.h>intmain(){inti;floattotal=0;for(i=0;i<5;i++)/*i為年數,取值為0?4年?/total=(total+1000)/(l+0.0063*12);/?累計算出年初存款數額,第五次的計算結果即為題解ッprintf("Hemustsave%.2fatfirst.\n",total);}運行結果Hemustsave4039.44atfirst怎樣存錢利最大假設銀行整存整取存款不同期限的月息利率分別為:0.63%期限=1年0.66%期限=2年0.69%期限=3年0.75%期限=5年0.84%期限=8年利息=本金?月息利率?12?存款年限。現在某人手中有2000元錢,請通過計算選擇ー?種存錢方案,使得錢存入銀行20年后得到的利息最多(假定銀行對超過存款期限的那一部分時間不付利息)。問題分析與算法設計為了得到最多的利息,存入銀行的錢應在到期時馬上取出來,然后立刻將原來的本金和利息加起來再作為新的本金存入銀行,這樣不斷地滾動直到滿20年為止,由于存款的利率不同,所以不同的存款方法(年限)存20年得到的利息是不一樣的。分析題意,設2000元存20年,其中1年存il次,2年存i2次,3年存i3次,5年存i5次,8年存i8次,則到期時存款人應得到的本利合計為:2000*(l+ratel)il*(l+rate2)i2*(l+rate3)i3*(l+rate5)i5*(l+rate8)i8其中rateN為對應存款年限的利率。根據題意還可得到以下限制條件:0<=i8<=20<=i5<=(20-8*i8)/50<=i3<=(20-8*i8-5*i5)/30<=i2<=(20-8*i8-5*i5-3*i3)/20<=il=20-8*i8-5*i5-3*i3-2*i2可以用窮舉法窮舉所有的i8、i5、i3、i2和il的組合,代入求本利的公式計算出最大值,就是最佳存款方案。程序說明與注釋#include<stdio.h>#include<math.h>intmain(){inti8,i5,i3,i2,il,n8,n5,n3,n2,nl;floatmax=0,term;for(i8=0戸8v3;i8++)/*窮舉所有可能的存款方式?/for(i5=0;i5<=(20-8*i8)/5;i5++)for(i3=0;i3<=(20-8*i8-5*i5)/3;i3++)for(i2=0;i2V=(20-8*i8-5*i5-3*i3)/2;i2++){il=20-8*i8-5*i5-3*i3-2*i2;term=2000.0*pow((double)(l+0.0063*12),(double)il)*pow((double)(l+2*0.0063*12),(double)i2)*pow((double)(l+3*0.0069*12),(double)i3)*pow((double)(l+5*0.0075*12)/(double)i5)*pow((double)(l+8*0.0084*12)z(double)i8);/?計算到期時的本利合計ッif(term>max)(max=term;nl=il;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",nl);printf("Toal:%,2f\nn,max);/?輸出存款方式?/}?運行結果Formaxinumprofit,heshouldsosavehismoneyinabank:madefixeddepositfor8year:Otimesmadefixeddepositfor5year:4timesmadefixeddepositfor3year:Otimesmadefixeddepositfor2year:Otimesmadefixeddepositfor1year:OtimesTotal:8841.01可見最佳的存款方案為連續四次存5年期。?思考題某單位對職エ出售住房,每套為2萬元。買房付款的方法是:一次交清,優惠20%從第一年開始,每年年初分期付款:5年交清,優惠50%;10年交清,優惠10%;20年交清,沒有優惠。現在有人手中正好有2萬元,若假定在今后20年中物價和銀行利率均保持不變,問他應當選擇哪種付款方式可以使應付的錢最少?捕魚和分魚A、B、C、D、E五個人在某天夜里合伙去捕魚,到第二天凌晨時都疲憊不堪,于是各自找地方睡覺。口上三桿,A第一個醒來,他將魚分為五份,把多余的一條魚扔掉,拿走自己的ー份。B第二個醒來,也將魚分為五份,把多余的一條魚扔掉,保持走自己的ー份。C,D、E依次醒來,也按同樣的方法拿走魚。問他們合伙至少捕了多少條魚?問題分析與算法設計根據題意,總計將所有的魚進行了五次平均分配,每次分配時的策略是相同的,即扔掉?條魚后剩ド的魚正好分成五份,然后拿走自己的一份,余下其它的四份。假定色的總數為X,則X可以按照題目的要求進行五次分配:X-1后可被5整除,余下的缶.為4*(X-1)、50若X滿足上述要求,則X就是題目的解。程序說明與注釋#include<stdio.h>intmain(){intn,i,x,flag=l;/*flag:控制標記?/for(n=6;flag;n++)/?采用試探的方法。令試探值n逐步加大?/{for(x=n,i=l&&flag;i<=5;i++)if((x-l)%5==0)x=4*(x-l)/5;elseflag=O;/?若不能分配則置標記falg=O退出分配過程?/if(flag)break;/?若分配過程正常結束則找到結果退出試探的過程?/elseflag=l;/?否則繼續試探下ー個數?/)printf("Totalnumberoffishcatched=%d\n",n);/?輸出結果?/)運行結果Totalnumberoffishcatched=3121問題的進ー步討論程序采用試探法,試探的初值為6,每次試探的步長為1。這是過分保守的做法。可以在進ー步分析題目的基礎上修改此值,增大試探的步長值,以減少試探次數。思考題請使用其它的方法求解本題。出售金魚買賣提將養的ー缸金魚分五次出售系統上一次賣出全部的一半加二分之一條;第二次賣出余下的三分之一加三分之一條;第三次賣出余下的四分之一加四分之一條:第四次賣出余下的五分之ー加五分之一條;最后賣出余下的11條。問原來的魚缸中共有兒條金魚?問題分析與算法設計題H中所有的魚是分五次出售的,每次賣出的策略相同;第j次賣剩下的(j+1)分之一再加l/(j+l)條。第五次將第四次余下的11條全賣了。假定第j次魚的總數為X,則第j次留下:x-(x+l)/(j+l)當第四次出售完畢時,應該剩ド11條。若X滿足上述要求,則X就是題目的解。應當注意的是:"(x+l)/(j+l)"應滿足整除條件。試探X的初值可以從23開始,試探的步長為2,因為X的值一定為奇數。程序說明與注釋#include<stdio.h>intmain(){inti,j,n=O,x;/*n為標志變量?/for(i=23;n==0;i+=2)/?控制試探的步長和過程?/<for(j=l,x=i;jv=4&&x>=ll;j++)/?完成出售四次的操作*/if((x+l)%(j+l)==O)/?若滿足整除條件貝リ進行實際的出售操作?/x-=(x+l)/(j+l);else{x=O;break;}/*否則停止計算過程?/if(j==5&&x==ll)/?若第四次余下11條則滿足題意?/{printf("Thereare%dfishesatfirst.\n",i);/?輸出結果?/n=l;/*控制退出試探過程?/}}}運行結果Thereare59fishesatfirst.思考題日本著名數學游戲專家中村義作教授提出這樣ー個問題;父親將2520個桔子分給六個兒子。分完后父親說;'、老大將分給你的桔子的1/8給老二;老二拿到后連同原先的桔子分1/7給老三;老三拿到后連同原先的枯了分1/6給老四;老四拿到后連同原先的桔子分1/5給老五;老五拿到后連同原先的桔子分1/4給老六;老六拿到后連同原先的桔子分1/3給老大“。結果大家手中的桔子正好一樣多。問六兄弟原來手中各有多少桔子?平分七筐魚甲、乙、丙三位魚夫出海打魚,他們隨船帶了21只蓼筐。當晚返航時,他們發現有七筐裝滿了魚,還有七筐裝了半筐魚,另外七筐則是空的,由于他們沒有秤,只好通過目測認為七個滿筐魚的重量是相等的,7個半筐魚的重量是相等的。在不將魚倒出來的前提下,怎樣將魚和筐平分為三份??問題分析與算法設計根據題意可以知道:每個人應分得七個算筐,其中有3.5筐魚。采用ー個3*3的數組a來表示三個人分到的東西。其中每個人對應數組a的一行,數組的第。列放分到的魚的整筐數,數組的第I列放分到的半筐數,數組的第2列放分到的空筐數。由題目可以推出:。數組的每行或每列的元素之和都為7:。對數組的行來說,滿筐數加半筐數=3.5;?每個人所得的滿筐數不能超過3筐:。每個人都必須至少有1個半筐,且半筐數一定為奇數對于找到的某種分魚方案,三個人誰拿哪ー份都是相同的,為了避免出現重復的分配方案,可以規定:第二個人的滿筐數等于第一個人的滿筐數;第二個人的半筐數大于等于第一個人的半筐數。?程序說明與注釋#include<stdio.h>inta[3][3],count;intmain(){inti,j,k,m,n,flag;printf("Itexistspossibledistribtionplans:\n");for(i=0;iv=3;i++)/?試探第一個人滿筐a[〇][〇]的值,滿筐數不能>3ツ{a[0][0]=i;for(j=i;j<=7-i&&jv=3;j++)/?試探第二個人滿筐a[l][〇]的值,滿筐數不能>3ツ<a[l][O]=j;if((a[2][0]=7-j-a[〇][〇])>3)continue;/?第三個人滿筐數不能>3ツif(a[2][0]<a[l][0])break;/?要求后一個人分的滿筐數>=前一個人,以排除重復情況?/for(k=l;kv=5;k+=2)/?試探半筐a[0][1]的值,半筐數為奇數?/{a[O][l]=k;for(m=l;m<7-k;m+=2)/?試探半筐a[l][l]的值,半筐數為奇數?/<a[l][l]=m;a[2][l]=7-k-m;for(flag=l,n=0;flag&&n<3;n++)/?判斷每個人分到的魚是3.5筐,flag為滿足題意的標記變量?/if(a[n][0]+a[n][l]<7&&a[n][0]*2+a[n][l]==7)a[n][2]=7?a[n][0]?a[n]ロ];/?計算應得到的空筐數量?/elseflag=O;/?不符合題意則置標記為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][l],a[n][2]);})})}?*運行結果Itexistspossibledistributionplans:No.lFullbasketSemi-basketEmptyfisherA:151fisherB:313fisherC:313No.2FullbasketSemi-basketEmptyfisherA:232fisherB:232fisherC:313?思考題晏會上數學家出了一道難題:假定桌子上有三瓶啤酒,癬瓶子中的酒分給兒個人喝,但喝各瓶酒的人數是不一樣的。不過其中有一個人喝了每ー瓶中的酒,且加起來剛好是ー瓶,請問喝這三瓶酒的各有多少人?(答案:喝三瓶酒的人數分別是2人、3人和6人)整數趣題有限5位數個位數為6且能被3整除的五位數共有多少?題目分析與算法設計根據題意可知,滿足條件的五位數的選擇范圍是10006、10016o.〇99996。可設基礎數i=1000,通過計算i*10+6即可得到欲選的數(i的變化范圍是1000?999),再判斷該數能否被3整除。程序說明與注釋#include<stdio.h>intmain(){longinti;intcount=0;/*count:統計滿足條件的五位數的個數?/for(i=1000;i<9999;i++)if(!((i*10+6)%3))/?判斷所選的數能否被3整除*/count++;/*若滿足條件則計數ッprintf("count=%d\n",count);)運行結果count=3000?思考題求100到1000之間有多少個其數字之和為5的整數。(答案:104,113,122,131,140,203,212,221,230,302,311,320,401,410,500)8除不盡的自然數ー個自然數被8除余1,所得的商被8除也余1,再將第二次的商被8除后余フ,最后得到ー個商為a。又知這個自然數被17除余4,所得的商被1フ除余15,最后得到ー個商是a的2倍。求這個自然數。?問題分析與算法設計根據題意,可設最后的商為i(i從。開始取值),用逆推法可以列出關系式:(((i*8+7)*8)+l)*8+l=((2*i*17)+15)*18+4再用試探法求出商i的值。?程序說明與注釋#include<stdio.h>intmain(){inti;for(i=0;;i++)/?試探商的值?/if(((i*8+7)*8+l)*8+l==(34*i+15)*17+4){/?逆推判斷所取得的當前i值是否滿足關系式?//*若滿足則輸出結果?/printf("Therequirednumberis:%d\n",(34*i+15)*17+4);break;/?退出循環?/})?運行結果Therequirednumberis:1993ー個奇異的三位數ー個自然數的七進制表達式是一個三位數,而這個自然數的九進制表示也是ー個三位數,且這兩個三位數的數碼正好相反,求這個三位數。問題分析與算法設計根據題意可知,七進制和九進制表示的這全自然數的每一位一定小于7,可設其七進制數形式為kji(i、j、k的取值分別為1?6),然后設其九進制表示形式為ijk。程序說明與注釋#include<stdio.h>intmain(){intfor(i=l;i<7;i++)for(j=0;j<7;j++)for(k=l;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"zkjjziJzkzi*9*9+j*9+k);}}運行結果Thespecialnumberwith3digitsis:503(7)=305(9)=248(10)4位反序數設N是ー個四位數,它的9倍恰好是其反序數,求N。反序數就是將整數的數字倒過來形成的整數。例如:1234的反序數是4321。問題分析與算法設計可設整數N的千、百、十、個位為i、j、k、I,其取值均為0?9,則滿足關系式:(i*103+j*102+10*k+l)*9=(l*103+k*102+10*j+i)的i、j、k、I即構成N。程序說明與注釋#include<stdio.h>intmain(){inti;for(i=1002;i<llll;i++)/?窮舉四位數可能的值?/if(i%10*1000+i/10%10*100+i/100%10*10+i/1000==i*9)/*判斷反序數是否是原整數的9倍?/printf("Thenumbersatisfiedstatsconditionis:%d\n",i);/*若是則輸出?/}運行結果Thenumbersatisfiedstatesconditionis:1089求車速ー輛以固定速度行駛的汽車,司機在上午10點看到里程表上的讀數是ー個對稱數(即這個數從左向右讀和從右向左讀是完全ー樣的),為95859。兩小時后里程表上出現了一個新的對稱數。問該車的速度是多少?新的対稱數是多少?問題分析與算法設計根據題意,設所求對稱數為i,其初值為95589,對其依次遞增取值,將i值的每一位分解后與其對稱位置上的數進行比較,若每個對稱位置上的數皆相等,則可判定i即為所求的對稱數。程序說明與注釋#include<stdio.h>intmain(){intt,a[5];/?數組a存放分解的數字位ッlongintk,i;for(i=95860;;i++)/?以95860為初值,循環試探?/<for(t=0,k=100000;k>=10;t++)/?從高到低分解所取i值的每位數?/{/?字,依次存放于a[〇]?a[5]中?/a[t]=(i%k)/(k/10);k/=10;}if((a[0]==a[4])&&(a[l]==a[3]))printf("Thenewsymmetricalnumberkelometersis:%d%d%d%d%d\n",a[0],a[l],a[2],a[3],a[4]);printf("Thevelocityofthecaris:%.2f\n",(1-95859)/2.0);break;}}運行結果Thenewsymmetricalnumberkelometersis:95959.Thevelocityofthecaris:50.00思考題將一個數的數碼倒過來所得到的新數叫原數的反序數。如果?個數等于它的反序數,則稱它為對稱數。求不超過1993的最大的二進制的對稱數。由兩個平方三位數獲得三個平方二位數已知兩個平方三位數abc和xyz,其中a、b、c、x、y、z未必是不同的:而ax、by、cz是三個平方二位數。請編程求三位數abc和xyz。?問題分析與算法設計任取兩個平方三位數n和nl,將n從高向低分解為a、b、c,將n!從高到低分解為x、y、z。判斷ax、by、cz是否均為完全平方數。?程序說明與注釋#include<stdio.h>#include<math.h>voidf(intn,float*s);intmain(){inti,t;floata[3],b[3];print("Thepossibleperfectsquarescombinationsare:\n");for(i=ll;i<=31;++i)〃窮舉平方三位數的取值范圍for(t=ll;t<=31;++t){f(i*i,a);〃分解平方三位數的各位,每位數字分別存入數組中f(t*t,b);if(sqrt(a[0]*10+b[0])==(int)sqrt(a[〇]*10+b[〇])&&sqrt(a[l]*10+b[l])==(int)sqrt(a[l]*10+b[l])&&sqrt(a[2]*10+b[2])==(int)sqrt(a[2]*10+b[2]))printf("%dand%d\n,i*i,t*t");〃若三個新的數均是完全平方數,則輸出}分解三位數n的各位數字,將各個數字從高到低依次存入指針s所指向的數組中 */voidf(intn,float*s){intk;for(k=1000;k>=10;++s)<s=(n%k)/(k/10);k/=10;))運行結果Thepossibleperfectsquarescombinationsare:400and900841and196思考題求這樣ー個三位數,該三位數等于其每位數字的階乘之和。即abc=a!+b!+c!(正確結果:145=1!+4!+5!)阿姆斯特朗數如果ー個正整數等于其各個數字的立方和,則稱該數為阿姆斯特朗數(亦稱為自戀性數)。如407=43+03+73就是ー個阿姆斯特朗數。試編程求1000以內的所有阿姆斯特朗數。問題分析與算法設計可采用窮舉法,依次取1000以內的各數(設為i),將i的各位數字分解后,據阿姆斯特朗數的性質進行計算和判斷。程序說明與注釋#include<stdio.h>intmain(){inti,t,k,a[3];printf("TherearefoilwingArmstrongnumbersmallerthan1000:\n");for(i=2;i<1000;i++)/?窮舉要判定的數i的取值范圍2?100〇?/{for(t=0,k=1000;k>=10;t++)/*截取整數i的各位(從高向低位)*/{a[t]=(i%k)/(k/10);/?分別賦于a[0]~a[2)*/k/=10;)if(a[0]*a[0]*a[0]+a[l]*a[l]*a[l]+a[2]*a[2]*a[2]==i)/*判斷i是否為阿姆斯特朗數?/printf("%5dソ);/?若滿足條件,則輸出?/)printf("\n");}運行結果TherearefollowingArmstrongnumbersmallerthan1000:153370371407完全數如果ー個數恰好等于它的因子之和,則稱該數為、、完全數”。問題分析與算法設計根據完全數的定義,先計算所選取的整數a(a的取值1?1000)的因子,將各因子累加于m,若m等于a,則可確認a為完全數。程序說明與注釋#include<stdio.h>intmain(){intprintf("Therearefollowingperfectnumberssmallerthan1000:\n");for(a=l;a<1000;a++)/?循環控制選取!~1000中的各數進行判斷?/(for(m=0,i=l;iv=a/2;i++)/?計算a的因子,并將各因子之和m=a,則a是完全數輸出?/if(!(a%i))m+=i;if(m==a)printf("%4dHza);}printf("\nu);}?運行結果TTherearefollowingperfectnumberssmallerthan1000:628496親密數如果整數A的全部因子(包括1,不包括A本身)之和等于B;且整數B的全部因子(包括1,不包括B本身)之和等于A,則將整數A和B稱為親密數。求3000以內的全部親密數。?問題分析與算法設計按照親密數定義,要判斷數a是否有親密數,只要計算出a的全部因子的累加和為b,再計第b的全部因子的累加和為n,若n等于a則可判定a和b是親密數。計算數a的各因子的算法:用a依次對i(i=l?a/2)進行模運算,若模運算結果等于〇,則i為a的ー個因子;否則i就不是a的因子。?程序說明與注釋#include<stdio.h>intmain(){inta,i,b,n;printf("Therearefollowingfriendly-numberspairsmallerthan3000:\n");for(a=l;av300〇;a++)/?窮舉1000以內的全部整數?/{for(b=0,i=l;iv=a/2;i++)/*計算數a的各因子,各因子之和存放于b*/if(!(a%i))b+=i;/*計算b的各因子,各因子之和存于n*/for(n=0,i=l;iv=b/2;i++)if(!(b%i))n+=i;if(n==a&&avb)printf("%4d..%4dツa,b);/?若n=a,則a和b是ー對親密數,輸出?/}}.運行結果Therearefollowingfriendly-numberspairsmallerthan3000:220..2841184..12102620..2924自守數自守數是指ー個數的平方的尾數等于該數自身的自然數。例如:252=625762=577693762=87909376請求出200000以內的自守數?問題分析與算法設計若采用、、求出ー個數的平方后再截取最后相應位數’’的方法顯然是不可取的,因為計算機無法表示過大的整數。分析手工方式下整數平方(乘法)的計算過程,以376為例:376被乘數X376乘數2256第一個部分積=被乘數?乘數的倒數第一位2632第二個部分積=被乘數?乘數的倒數第二位1128第三個部分積=被乘數?乘數的倒數第三位141376積本問題所關心的是積的最后三位。分析產生積的后三位的過程,可以看出,在每一次的部分積中,并不是它的每一位都會對積的后三位產生影響。總結規律可以得到:在三位數乘法中,對積的后三位產生影響的部分積分別為:第一個部分積中:被乘數最后三位*乘數的倒數第一位第二個部分積中:被乘數最后二位?乘數的倒數第二位第三個部分積中:被乘數最后一位?乘數的倒數第三位將以上的部分積的后三位求和后截取后三位就是三位數乘積的后三位。這樣的規律可以推廣到同樣問題的不同位數乘積。按照手工計算的過程可以設計算法編寫程序。?程序說明與注釋#include<stdio.h>intmain(){longmul,number,k,ll,kk;printf("Itexistsfollowingautomorphicnmberssmallthan200000:\n");for(number=0;number<200000;number++){for(mul=number,k=l;(mul/=10)>0;k*=10);/?由number的位數確定截取數字進行乘法時的系數k*/kk=k*10;/*kk為截取部分積時的系數?/mul=0;/?積的最后n位?/11=10;/*n為截取乘數相應位時的系數ッwhile(k>0){mul=(mul+(number%(k*10))*(number%ll-number%(ll/10)))%kk;/*(部分積+截取被乘數的后N位*截取乘數的第M位),%kk再截取部分積?/k/=10;/*k為截取被乘數時的系數?/ll*=10;}if(number==mul)/?判斷若為自守數則輸出?/printf("%ld",number);}運行結果Itexstsfollowingautomorphicnumbnerssmallerthan200000:01562576376625937690625109376回文數打印所有不超過n(取n<256)的其平方具有對稱性質的數(也稱回文數)。問題分析與算法設計對于要判斷的數n,計算出其平方后(存于a),將a的每一位進行分解,再按a的從低到高的順序將其恢復成一個數k(如n=13,則a=169且k=961),若a等于k則可判定n為回亠數。程序說明與注釋原程序好像有錯,而且比較費解,現基于原程序修改如下(如果讀者還發現錯誤請提出):#include<stdio.h>intmain(void){intm[16],n,i,t,count=0;longunsigneda,k;printf("No.numberit'ssquare(palindrome)\n");for(n=l;n<256;n++)/?窮舉n的取值范圍?/{k=O;t=l;a=n*n;/*計算n的平方?/for(i=0;a!=0;i++)/?從低到高分解數a的每一位存于數組m[0]-m[16]*/{m[i]=a%10;〃這個是取得a的個位,整個循環合起來就可以取得各個位a/=10;)intj=0;for(i-;jvi;j++,i-)〃因為n的平方的各個位都存在數組中了,下面判斷是不是對稱if(m[j]!=m[i])break;〃只要有一位不是對稱,那就說明不是對稱,就可以退出了〃所有的位都對稱就說明是對稱了,這樣就可以打印出結果了if(j>=i)printf("%2d%10d%10d\n",++count,n,n*n);}return0;}運行結果No.numberit'ssquare(palindrome)11122433941112152248462667671011020181111232191211464110202408041121244944〃下面程序是原來的,有錯,而且費解#include<stdio.h>intmain(void){intm[16]/n/i/t/count=0;longunsigneda,k;printf("No.numberiゼssquare(palindrome)\n");for(n=l;nv256;n++)/?窮舉n的取值范圍?/(k=0;t=l;a=n*n;/?計算n的平方?/for(i=l;a!=0;i++)/?從低到高分解數a的每一位存于數組m[l]-m[16]*/{m[i]=a%10;〃安安注:這個是取得a的個位,整個循環合起來就可以取得各個位,并存于數組中,為了是下面判斷是不是對稱a/=10;}for(;i>l;i-){k+=m[i-l]*t;t*=10;}if(k==n*n)printf("%2d%10d%10d\n,',+4-countznzn*n);}return0;}?運行結果No.numberit'ssquare(palindrome)111224339411121522484626676710110201811112321912114641求具有abcd=(ab+cd)2性質的四位數3025這個數具有一種獨特的性質:將它平分為ニ段,即30和25,使之相加后求平方,即(30+25)2,恰好等于3025本身。請求出具有這樣性質的全部四位數。?問題分析與算法設計具有這種性質的四位數沒有分布規律,可以采用窮舉法,對所有四位數進行判斷,從而篩選出符合這種性質的四位數。具體算法實現,可任取ー個四位數,將其截為兩部分,前兩位為a,后兩位為b,然后套用公式計算并判斷。?程序說明與注釋#include<stdio.h>intmain(){intn,a,b;printf("Therearefollowingnumber

溫馨提示

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

評論

0/150

提交評論