《演算法競賽入門經典》上機練習——第二章_c

來源:互聯網
上載者:User

習題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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.