習題2-1 位元(digit)
輸入一個不超過10^9的正整數,輸出它的位元。例如12735的位元是5。請不要使用任何數學函數,只用四則運算和迴圈語句實現。
#include <stdio.h>int main(){ int x,num=0; scanf("%d",&x); while(x) { x/=10; num++; } printf("%d\n",num);return 0;}
習題2-2 水仙花數(daffodil)
輸出100~999中的所有水仙花數。若3位元ABC滿足ABC=A^3+B^3+C^3,則稱其為水仙花數。例如153=1^3+5^3+3^3,所以153是水仙花數。
#include <stdio.h>int main(){ int i,a,b,c; for(i=100; i<=999; i++) { a = i%10; /*個位*/ b = i/10%10; /*十位*/ c = i/100; /*百位*/ if(i == a*a*a + b*b*b + c*c*c) printf("%d\n",i); }return 0;} 結果:三位水仙花數有:153,370,371,407
習題2-3 韓信點兵(hanxin)
相傳韓信才智過人,從不直接清點自己軍隊的人數,只要讓士兵先後以三人一排、五人一排、七人一排地變換隊形,而他每次只掠一眼隊伍的排尾就知道總人數了。輸入3個非負整數a,b,c,表示每種隊形排尾的人數(a<3,b<5,c<7),輸出總人數的最小值(或報告無解)。已知總人數不小於10,不超過100。
範例輸入:2 1 6
範例輸出:41
範例輸入:2 1 3
範例輸出:No answer
#include <stdio.h>int main(){ int i,a,b,c; scanf("%d%d%d",&a,&b,&c); for(i=10; i<=100; i++) { if(i%3==a && i%5==b && i%7==c) { printf("%d\n",i); break; } } if(i == 101) printf("No answer\n");return 0;}
習題2-4 倒三角形(triangle)
輸入正整數n<=20,輸出一個n層的倒三角形。例如n=5時輸出如下:
######### ####### ##### ### #
#include <stdio.h>int main(){ int n,i,j; scanf("%d",&n); for(i=n;i>=1;i--) { for(j=1;j<=n-i;j++) printf(" ");for(j=1;j<=2*i-1;j++) printf("#"); printf("\n"); }return 0;}
習題2-5 統計(stat)
輸入一個正整數n,然後讀取n個正整數a1,a2,...,an,最後再讀一個正整數m。統計a1,a2,...,an中有多少個數小於m。提示:如果重新導向和fopen都可以使用,哪個比較方便。
這道不會。。。歡迎指教。
習題2-6 調和級數(harmony)
輸入正整數 n,輸出 H(n) = 1 + 1/2 + 1/3 +...+ 1/n 的值,保留3位小數。例如n=3時答案為1.833。
#include <stdio.h>int main(){ int n,i; double H = 0; scanf("%d",&n); for(i=1; i<=n; i++) H += 1.0/i; printf("%.3lf\n",H);return 0;}
習題2-7 近似計算(approximation)
計算pi/4 = 1 - 1/3 + 1/5 - 1/7 + ...,直到最後一項小於10^(-6)。
#include <stdio.h>int main(){ int i=1,flag=1; double sum=0,item=1.0; while(item>=1.0/1000000){sum += flag*item;flag *= -1;i += 2;item = 1.0/i; } printf("pi = %lf\n",sum*4); return 0;}
習題2-8 子序列的和(subsequence)
輸入兩個正整數n<m<10^6,輸出1/n^2 + 1/(n+1)^2 +...+ 1/m^2,保留5位小數。例如,n=2,m=4 時答案是0.42361;n=65536,m=655360 時答案為0.00001,。注意:本題有陷阱。
#include <stdio.h>int main(){ int i,n,m; double sum=0; scanf("%d%d",&n,&m); for(i=n;i<=m;i++) sum += 1.0/i/i; printf("%.5lf\n",sum); return 0;} 本題陷阱:當n或m比較大時,i * i 會溢出,不能用 1.0 / ( i * i ) ,應該用 1.0 / i / i 。 或者改用long long資料類型。
習題2-9 分數化小數(decimal)
輸入正整數a,b,c,輸出a/b的小數形式,精確到小數點後c位。a,b<=10^6,c<=100。例如 a=1,b=6,c=4 時應輸出 0.1667。
#include <stdio.h>int main(){ int a,b,c; scanf("%d%d%d",&a,&b,&c); printf("%.*lf\n",c,1.0*a/b); /*新知識:格式控制符中,* 可由後邊的變數替代。*/return 0;}
此種方法的問題是,當c較大時,超過十幾位小數後邊的小數部分都只顯示零,不知道為什麼。
以下是逐位計算小數的方法,就完全沒問題了。(此段代碼非我所寫,注釋是我加的,代碼出處見部落格尾。)
#include <stdio.h> int main(void) { int a,b,c,mod,re,i,m,x,y; while(scanf("%d%d%d",&a,&b,&c)==3) { printf("%d",a/b); /*輸出整數部分*/ mod=a%b; if(c>0) { printf("."); for(i=1;i<c;i++) /*逐位計算輸出c-1位小數*/ { m=mod*10; re=m/b; printf("%d",re); mod=m%b; } m=mod*10; x=m/b; mod=m%b; /*往後多算一位,四捨五入到我們所需的最後一位*/ m=mod*10; y=m/b; if(y>=5) x++; printf("%d\n",x); /*輸出最後一位小數*/ } } return 0; }
習題2-10 排列(permutation)
用 1,2,3,...,9 組成 3 個三位元 abc,def 和 ghi,每個數字恰好使用一次,要求 abc : def : ghi = 1 : 2 : 3。輸出所有解。提示:不必太動腦筋。
#include<stdio.h>int arr[10] = {0};/*數組arr用來記錄1~9每個數字是否出現,與下標一一對應,出現為1,否則為0*/int main(){int a,b,c,d,e,f,g,h,i,abc,def,ghi,t,sum;for(a=1;a<=3;a++) /*a最大為3*/ for(b=1;b<=9;b++) for(c=1;c<=9;c++) for(d=2;d<=6;d++) /*d最小為2,最大為6*/ for(e=1;e<=9;e++) for(f=1;f<=9;f++) for(g=3;g<=9;g++) /*g最小為3*/ for(h=1;h<=9;h++) for(i=1;i<=9;i++) { for(t=1;t<=9;t++) arr[t] = 0; arr[a] = 1;arr[b] = 1;arr[c] = 1;arr[d] = 1;arr[e] = 1;arr[f] = 1; arr[g] = 1;arr[h] = 1;arr[i] = 1;sum = 0; for(t=1;t<=9;t++) /*若數組累加和為9,表示1~9的數字全部出現*/ sum+=arr[t]; if(sum==9) { abc = a*100+b*10+c; def = d*100+e*10+f; ghi = g*100+h*10+i; if(abc*2==def && abc*3==ghi) printf("%d:%d:%d = 1:2:3\n",abc,def,ghi); } }return 0;}
結果:
192:384:576 = 1:2:3
219:438:657 = 1:2:3
273:546:819 = 1:2:3
327:654:981 = 1:2:3
還有網上的另一種方法,一定程度的逆向思維,精妙,運行速度比我的多層for迴圈嵌套快多了,我的程式迴圈次數有3*9*9*5*9*9*7*9*9 = 55801305次,而以下程式只有333-100 = 233次。
#include <stdio.h>int main(void){int x, y, z, a[10] = {0};for(x = 100; x < 333; x++){y = 2*x;z = 3*x;//令a[出現的數字] = 1a[x/100] = a[x/10%10] = a[x%10] = 1;a[y/100] = a[y/10%10] = a[y%10] = 1;a[z/100] = a[z/10%10] = a[z%10] = 1;int i, s = 0;for(i = 1; i < 10; i++)s += a[i];if(s == 9)printf("%d\t%d\t%d\n", x, y, z);for(i = 1; i < 10; i++)//重新賦值為0a[i] = 0;}return 0;}
若有錯誤遺漏歡迎指出,歡迎交流討論。
註:本文部分參考此篇部落格:http://blog.csdn.net/litiouslove/article/details/7891700