1. 程式人生 > >杭電OJ第11頁2000-2009道題(C語言)

杭電OJ第11頁2000-2009道題(C語言)

月的天數 3.1 clu else 要求 max 本質 轉換 err

1. ASCII碼排序

問題描述

輸入三個字符後,按各字符的ASCII碼從小到大的順序輸出這三個字符

Input:
輸入數據有多組,每組占一行,有三個字符組成,之間無空格

Output:
對於每組輸入數據,輸出一行,字符中間用一個空格分開

Sample:
輸入:qwe
      asd
      zxc
輸出:e w q
      a d s
      c x z

解題思路

字符,是以ascall碼的形式儲存的;跟整型數據是一樣的;
字符之間可以進行運算,本質上是ascall碼值的比較;
問題轉化為三個數的排序問題
擴展:小寫字母比大寫字母的ascall值大32

代碼

# include <stdio.h>

int main()
{
    char a, b, c, t;
    while(scanf("%c%c%c", &a,&b,&c) == 3)
    {
        char temp = getchar();  //重點地方,getchar吸收回車符(getchar函數從控制臺中讀取字符,直到按回車結束)
        printf("%c\n", temp);
        if(a > b)   {t = a;a = b;b = t;} //必有a <= b
        if(a > c)   {t = a;a = c;c = t;} //必有a <= c
        if(b > c)   {t = b;b = c;c = t;} //必有b <= c

        //a <= b <= c
        printf("%c %c %c\n", a, b, c);
    }

    return 0;
}

重點

getchar函數

讀取標準輸入的一個字符,直到按回車(識別到‘\n‘)為止
如果輸入多個字符,其他字符會被放在緩存區,等待後續getchar調用
返回值:相應字符的ascall值

scanf返回值的問題

  1. 正確輸入參數的個數
  2. EOF,輸入流已經結束。在Windows下,用戶按下CTRL+Z(會看到一個^Z字符)再按下回車,就表示輸入結束;Linux/Unix下使用CTRL+D表示輸入結束。

2. 計算兩點間的距離

問題描述

輸入兩點坐標(x1, y1), (x2, y2)

input:
輸入數據有多組,每組占一行,由4個實數組成,分別表示x1, y1, x2, y2,數據之間用空格隔開。

output:
對於每組輸入數據,輸出一行,結果保留兩位小數。

解題思路

歐式距離公式

代碼

#include <stdio.h>
#include <math.h>


int main()
{
    double x1, y1, x2, y2, dist;
    while(scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2) == 4)
    {
        getchar();
        dist = sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));

        printf("%.2f\n", dist);
    }


    return 0;
}

重點

scanf的輸入問題

  1. 輸入,數據之間用空格隔開
  2. double類型輸入必須使用%lf才能得到正確的值;輸出可以使用%f

3. 計算球的體積

問題描述

Problem Description
根據輸入的半徑值,計算球的體積。
 

Input
輸入數據有多組,每組占一行,每行包括一個實數,表示球的半徑。
 

Output
輸出對應的球的體積,對於每組輸入數據,輸出一行,計算結果保留三位小數。
 

Sample Input
1
1.5
 

Sample Output
4.189
14.137

Hint

#define PI 3.1415927

解題思路

v = 3/4 * pi * pow(r, 3)

代碼

#include <stdio.h>
#include <math.h>
#define PI 3.1415927

int main()
{
    double r, v;
    while(scanf("%lf", &r) == 1)
    {
        v = 4/3.0 * PI * pow(r, 3); //乘法和除法優先級相同
        printf("%.3f\n", v);
    }

    return 0;
}

重點

註意

必須是 4/3.0 → 1.33

如果是 4/3 → 1.00。最後答案也不對了

4. 求絕對值

問題描述

Problem Description
求實數的絕對值。
 

Input
輸入數據有多組,每組占一行,每行包含一個實數。
 

Output
對於每組輸入數據,輸出它的絕對值,要求每組數據輸出一行,結果保留兩位小數。
 

Sample Input
123
-234.00
 

Sample Output
123.00
234.00

解題思路

#include <math.h>中的fabs()函數

代碼

#include <stdio.h>
#include <math.h>


int main()
{
    double x;
    while(scanf("%lf", &x) == 1)
    {
        printf("%.2f\n", fabs(x));
    }

    return 0;
}

重點

<stdlib.h>中的abs(x),x只能是長整型

5. 成績轉換

問題描述

Problem Description
輸入一個百分制的成績t,將其轉換成對應的等級,具體轉換規則如下:
90~100為A;
80~89為B;
70~79為C;
60~69為D;
0~59為E;
 

Input
輸入數據有多組,每組占一行,由一個整數組成。
 

Output
對於每組輸入數據,輸出一行。如果輸入數據不在0~100範圍內,請輸出一行:“Score is error!”。
 

Sample Input
56
67
100
123
 

Sample Output
E
D
A
Score is error!

解題思路

可以用判斷if-else if-結構來做;
也可以用switch:case來做

代碼

#include <stdio.h>


int main()
{
    int score;
    while(scanf("%d", &score) == 1)
    {
        if(score < 0 || score > 100)    printf("Score is error!\n");
        else if(score >= 90)    printf("A\n");
        else if(score >= 80)    printf("B\n");
        else if(score >= 70)    printf("C\n");
        else if(score >= 60)    printf("D\n");
        else if(score >= 0)     printf("E\n");
    }

    return 0;
}

重點

switch case語句

switch(expression)
{
    case 1: printf();break; //expression == 1
    case 2:
    
    default: printf();
}

6. 第幾天

問題描述

Problem Description
給定一個日期,輸出這個日期是該年的第幾天。
 

Input
輸入數據有多組,每組占一行,數據格式為YYYY/MM/DD組成,具體參見sample input ,另外,可以向你確保所有的輸入數據是合法的。
 

Output
對於每組輸入數據,輸出一行,表示該日期是該年的第幾天。
 

Sample Input
1985/1/20
2006/3/12
 

Sample Output
20
71
 

解題思路

使用數組保存每個月的天數
判斷閏年/平年,改變2月天數

代碼

#include<stdio.h>
int main()
{
    int a,b,c;
    int d[13]={31,28,31,30,31,30,31,31,30,31,30,31};
    while(~scanf("%d/%d/%d",&a,&b,&c))
    {
        int num=0;
        for(int i=0;i<b-1;i++)
            num+=d[i];
        if(a%400==0||(a%4==0&&a%100!=0))
        {
            if(b>2)
                num+=c+1;
            else
                num+=c;
        }
        else
            num+=c;
        printf("%d\n",num);
    }
    return 0;
} 

重點

scanf取反

可以經常在ACM代碼中看到 while(~scanf("%d",&n)){ } 這樣的代碼,意思是在讀到輸入結尾時循環也結束。

一般在讀到輸入流結尾時,scanf返回的是EOF。

EOF是在頭文件stdio.h中定義的常量,一般為-1。

-1 的原碼是10000001,反碼是1111110,補碼是11111111

~EOF則是對EOF進行按位取反操作,則為00000000。所以while條件不滿足,循環結束。

7. 求n個數中奇數的乘積

問題描述

Problem Description
給你n個整數,求他們中所有奇數的乘積。
 

Input
輸入數據包含多個測試實例,每個測試實例占一行,每行的第一個數為n,表示本組數據一共有n個,接著是n個整數,你可以假設每組數據必定至少存在一個奇數。
 

Output
輸出每組數中的所有奇數的乘積,對於測試實例,輸出一行。
 

Sample Input
3 1 2 3
4 2 3 4 5
 

Sample Output
3
15

解題思路

兩個while解決輸入n個數的控制問題
奇數:除以2的余數為1

代碼

#include <stdio.h>
#define maxn 100000
int main()
{
    int n, x;
    int i = 0;
    int num[maxn];
    while(scanf("%d", &n) != EOF)
    {
        int ans = 1;
        while(n--){
            scanf("%d", &x);
            if(x%2 == 1)    ans *= x;
        }
        printf("%d\n", ans);
    }
    

    return 0;
}

重點

詳細讀題目,n個數的輸入,明確了輸入個數。

8. 平方和與立方和

問題描述

Problem Description
給定一段連續的整數,求出他們中所有偶數的平方和以及所有奇數的立方和。
 

Input
輸入數據包含多組測試實例,每組測試實例包含一行,由兩個整數m和n組成。
 

Output
對於每組輸入數據,輸出一行,應包括兩個整數x和y,分別表示該段連續的整數中所有偶數的平方和以及所有奇數的立方和。
你可以認為32位整數足以保存結果。
 

Sample Input
1 3
2 5
 

Sample Output
4 28
20 152

解題思路

偶數 %2 == 0:pow(偶數,3)
奇數 %2 == 1:pow(奇數,3)

代碼

# include <stdio.h>
# include <math.h>

int main()
{
    int x, y;
    //int even_sum = 0;
    //int odd_sum = 0;
    while(~scanf("%d %d", &x, &y)){
        int even_sum = 0;
        int odd_sum = 0;

        if(x > y){
            int temp;
            temp = x;
            x = y;
            y = temp;
        }

        for(;x <= y; x++)
        {
            if(x%2 == 0) even_sum += pow(x, 2);
            else odd_sum += floor(pow(x, 3) + 0.5);
        }

    printf("%d %d\n", even_sum, odd_sum);
    }
    
    return 0;
}

重點

考慮輸入大小問題

pow(5, 3)在整型int輸出使會舍入為124,不會返回125

更安全的寫法 floor(pow(x, 3) + 0.5)

9. 數值統計

問題描述

Problem Description
統計給定的n個數中,負數、零和正數的個數。
 

Input
輸入數據有多組,每組占一行,每行的第一個數是整數n(n<100),表示需要統計的數值的個數,然後是n個實數;如果n=0,則表示輸入結束,該行不做處理。
 

Output
對於每組輸入數據,輸出一行a,b和c,分別表示給定的數據中負數、零和正數的個數。
 

Sample Input
6 0 1 2 3 -1 0
5 1 2 3 4 0.5
0 
 

Sample Output
1 2 3
0 0 5

解題思路

註意條件 n=0,break

代碼

#include <stdio.h>

int main()
{
    int n;
    double x;
    while(scanf("%d", &n) != EOF){
        int num_negative = 0;
        int num_zero = 0;
        int num_positive = 0;

        if(n == 0)  break;
        while(n--)
        {
            scanf("%lf", &x);
            if(x > 0) num_positive += 1;
            else if(x < 0) num_negative += 1;
            else num_zero += 1;
        }
        printf("%d %d %d\n", num_negative, num_zero, num_positive);
    }

    return 0;   
}

重點

仔細看題

10. 求數列的和

問題描述

Problem Description
數列的定義如下:
數列的第一項為n,以後各項為前一項的平方根,求數列的前m項的和。
 

Input
輸入數據有多組,每組占一行,由兩個整數n(n<10000)和m(m<1000)組成,n和m的含義如前所述。
 

Output
對於每組輸入數據,輸出該數列的和,每個測試實例占一行,要求精度保留2位小數。
 

Sample Input
81 4
2 2
 

Sample Output
94.73
3.41

解題思路

不想寫了,想什麽寫什麽

代碼

#include <stdio.h>
#include <math.h>

int main()
{
    double n;
    while(scanf("%lf", &n) != EOF)
    {
        double ans = 0.0;
        int m;
        scanf("%d", &m);
        while(m--){
            ans += n;
            n = sqrt(n);
        }
        printf("%.2f\n", ans);
    }

    return 0;
}

重點

同上

杭電OJ第11頁2000-2009道題(C語言)