1. 程式人生 > >【演算法競賽入門經典】【第一章】課後習題

【演算法競賽入門經典】【第一章】課後習題

今天心血來潮,決定將《演算法競賽入門經典》裡面的課後題,進行詳解,先來第一發。

習題1-1 平均數(average)

       對於第一題,相信即便是第一次接觸程式設計的人。只要稍稍瞭解一下C的語法,也可輕易解決這一題。所以我也不多說了直接上程式碼。

#include <stdio.h>

int main()
{
    int a, b, c;
    while(scanf("%d%d%d",&a,&b,&c)!=EOF){
        printf("%.3lf\n",(a+b+c)/3.0);
    }
    return 0;
}

習題1-2 溫度(temperature)

       題目連公式都給了,沒什麼好說的

#include <stdio.h>

int main()
{
    double f,c;
    while(scanf("%lf",&f)!=EOF){
        c = 5 * ( f - 32 ) / 9;
        printf("%.3lf\n",c);
    }
    return 0;
}


習題1-3 連續和(sum)

        這一題的話,我相信肯定會有一部分人在學完迴圈之後程式碼會這樣寫

#include <stdio.h>

int main()
{
    int n,sum,i;
    while(scanf("%d",&n)!=EOF){
        sum = 0;
        for(i = 1; i <= n; i++ )
            sum += i;
        printf("%d\n",sum);
    }
    return 0;
}

     或者是使用while之類的迴圈語句來做。但是我要說這樣不行,當然不是它不對,而是在演算法競賽中除了答案之外,我們最重視的就是效率了,用迴圈需要執行至少n次。然而如果我們使用遞增數列的求和公式的話,我們的效率將大大的提高,在演算法競賽中我們使用的是黑盒評測的模式,這種模式的特點就是隻關心結果而不關心過程。所以我們的程式碼應該這樣:

#include <stdio.h>

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        printf("%d\n",(n+1)*n/2);
    }
    return 0;
}


習題1-4 正弦和餘弦(sin cos)

#include <stdio.h>
#include <math.h>
int main()
{
    double n;
    while(scanf("%lf",&n)!=EOF){
        printf("%lf,%lf\n",sin(n),cos(n));
    }
    return 0;
}

       這一題中我們使用到了數學函式,其中大部分的數學函式均在 math.h 中。我還要說明一點在演算法競賽中我們只需要輸出結果,並不需要多餘的提示,不然你會發現你的答案會莫名的錯了。然而這個應該就是演算法競賽和實際程式設計中的區別之一。

習題1-5 距離(distance)

#include <stdio.h>
#include <math.h>
int main()
{
    double x1,y1,x2,y2;
    while(scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2)!=EOF){
        printf("%.3lf\n",sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
    }
    return 0;
}

習題1-6 偶數(odd)

       判斷偶數的方法有很多,這裡我就用我認為最簡單的方法

#include <stdio.h>

int main()
{
    int a;
    while(scanf("%d",&a)!=EOF){
        printf("%s\n",a%2?"no":"yes");
    }
    return 0;
}

習題1-7 打折(discount)

#include <stdio.h>

int main()
{
    int n;
    double monkey;
    while(scanf("%d",&n)!=EOF){
        monkey = 95 * n;
        if( n > 3)
            monkey *= 0.85;
        printf("%.3lf\n",monkey);
    }
    return 0;
}

習題1-8絕對值(abs)
 這一題有兩種方法,一種使用庫函式,一種不用。下面我使用不適用庫函式的方法吧:

#include <stdio.h>

int main()
{
    double n;
    while(scanf("%lf",&n)!=EOF){
        printf("%.2lf\n",n>0?n:-n);
    }
    return 0;
}

習題1-9 三角形(triangle)

        判斷三條邊是否可以構成三角形,我們可以使用任意兩邊和大於第三邊的方式:

#include <stdio.h>

int main()
{
    int a,b,c;
    while(scanf("%d%d%d",&a,&b,&c)!=EOF){
        if( a+b>c && a+c>b && b+c>a )
            printf("yes\n");
        else
            printf("no\n");
    }
    return 0;
}


習題1-10 年份(year)

①、普通年能被4整除且不能被100整除的為閏年。

②、世紀年能被400整除的是閏年

③、對於數值很大的年份,這年如果能整除3200,並且能整除172800則是閏年。如172800年是閏年,86400年不是閏年(這一點我們通常可以不用考慮)

於是程式碼如下:

#include <stdio.h>

int main()
{
    int year;
    while(scanf("%d",&year)!=EOF){
        if(year%400==0)
            printf("yes\n");
        else if(year%4==0&&year%100!=0)
            printf("yes\n");
        else
            printf("no\n");
    }
    return 0;
}

【第二章】課後習題:傳送門

【第三章】課後習題:傳送門