练习2-12 输出华氏-摄氏温度转换表

输入2个正整数lowerupperlowerupper≤100),请输出一张取值范围为[lowerupper]、且每次增加2华氏度的华氏-摄氏温度转换表。
温度转换的计算公式:C=5×(F−32)/9,其中:C表示摄氏温度,F表示华氏温度。
输入格式:
在一行中输入2个整数,分别表示lowerupper的值,中间用空格分开。
输出格式:
第一行输出:”fahr celsius”
接着每行输出一个华氏温度fahr(整型)与一个摄氏温度celsius(占据6个字符宽度,靠右对齐,保留1位小数)。
若输入的范围不合法,则输出”Invalid.”。
输入样例1:

  1. 32 35

输出样例1:

  1. fahr celsius
  2. 32 0.0
  3. 34 1.1

输入样例2:

  1. 40 30

输出样例2:

  1. Invalid.

解题思路:循环的范围就是 [lowerupper],变量每次自增 2 即可。

  1. #include <stdio.h>
  2. int main () {
  3. int m, n;
  4. scanf("%d %d", &m, &n);
  5. // 1.判断合法性
  6. if (m > n) {
  7. printf("Invalid.");
  8. return 0;
  9. }
  10. printf("fahr celsius\n");
  11. // 2.步长位2循环输出
  12. for (; m <= n; m += 2) {
  13. float celsius = 5 * (m - 32) / 9.0;
  14. printf("%d%6.1f\n", m, celsius);
  15. }
  16. return 0;
  17. }

运行结果

Case Hint Result Score Run Time Case
0 sample 1,结尾不到达upper Accepted 7 3 ms 0
1 sample 2,不合法数据 Accepted 1 3 ms 1
2 最大范围 Accepted 3 4 ms 2
3 最大边界点 Accepted 2 3 ms 3

练习2-13 求N分之一序列前N项和

本题要求编写程序,计算序列 1 + 1/2 + 1/3 + … 的前N项之和。
输入格式:
输入在一行中给出一个正整数N。
输出格式:
在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后6位。题目保证计算结果不超过双精度范围。
输入样例:

  1. 6

输出样例:

  1. sum = 2.450000

解题思路:根据题意可得通项公式为 PTA编程—循环1 - 图1,而题目所求即为 PTA编程—循环1 - 图2,因此使用循环即可。

  1. #include <stdio.h>
  2. int main() {
  3. int N;
  4. scanf("%d", &N);
  5. double sum = 0.0;
  6. for (int i = 1; i <= N; i++) {
  7. sum += 1.0 / i;
  8. }
  9. printf("sum = %.6f\n", sum);
  10. return 0;
  11. }
Case Hint Result Score Run Time Memory
0 sample等价 Accepted 9 3 ms 364 KB
1 N最小 Accepted 2 2 ms 296 KB
2 较大N Accepted 4 3 ms 376 KB

练习2-14 求奇数分之一序列前N项和

本题要求编写程序,计算序列 1 + 1/3 + 1/5 + … 的前N项之和。
输入格式:
输入在一行中给出一个正整数N。
输出格式:
在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后6位。题目保证计算结果不超过双精度范围。
输入样例:

  1. 23

输出样例:

  1. sum = 2.549541

解题思路:根据题意可得通项公式为 PTA编程—循环1 - 图3,而题目所求即为 PTA编程—循环1 - 图4,因此使用循环即可。

  1. #include <stdio.h>
  2. int main() {
  3. int N;
  4. scanf("%d", &N);
  5. double sum = 0.0;
  6. for (int i = 1; N > 0; i += 2) {
  7. sum += 1.0 / i;
  8. N--;
  9. }
  10. printf("sum = %.6f\n", sum);
  11. return 0;
  12. }
Case Hint Result Score Run Time Memory
0 sample等价 Accepted 9 2 ms 296 KB
1 N最小 Accepted 2 3 ms 224 KB
2 较大N Accepted 4 3 ms 220 KB

练习2-15 求简单交错序列前N项和

本题要求编写程序,计算序列 1 - 1/4 + 1/7 - 1/10 + … 的前N项之和。
输入格式:
输入在一行中给出一个正整数N。
输出格式:
在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后三位。题目保证计算结果不超过双精度范围。
输入样例:

  1. 10

输出样例:

  1. sum = 0.819

解题思路:根据题意可得通项公式为 PTA编程—循环1 - 图5,而题目所求即为 PTA编程—循环1 - 图6,因此使用循环即可。

  1. #include <stdio.h>
  2. int main() {
  3. int N;
  4. scanf("%d", &N);
  5. double sum = 0.0;
  6. for (int i = 1, sign = 1; N > 0; i += 3, sign *= -1) {
  7. sum += 1.0 / i * sign;
  8. N--;
  9. }
  10. printf("sum = %.3f\n", sum);
  11. return 0;
  12. }
Case Hint Result Score Run Time Memory
0 同sample Accepted 9 3 ms 260 KB
1 最小N Accepted 2 2 ms 368 KB
2 较大N Accepted 4 2 ms 384 KB

练习2-17 生成3的乘方表

输入一个非负整数n,生成一张3的乘方表,输出PTA编程—循环1 - 图7的值。可调用幂函数计算3的乘方。
输入格式:
输入在一行中给出一个非负整数n
输出格式:
按照幂的递增顺序输出n+1行,每行格式为“pow(3,i) = 3的i次幂的值”。题目保证输出数据不超过长整型整数的范围。
输入样例:

  1. 3

输出样例:

  1. pow(3,0) = 1
  2. pow(3,1) = 3
  3. pow(3,2) = 9
  4. pow(3,3) = 27

解题思路:本题最重要的是实现 pow(3, n) 函数,最笨的方式就是使用累乘。但是实际上题目要求输出连续的乘法结果,即有 PTA编程—循环1 - 图8,因此在输出下一个乘方时,我们不必再进行 n 次累乘,而是直接在前一项基础上再 ×3 :::tips 注意下方代码循环判断条件!当 n = 0 时也要输出,因此使用 do-while 循环更好。 :::

  1. #include <stdio.h>
  2. #define base 3
  3. int main() {
  4. int N;
  5. scanf("%d", &N);
  6. int product = 1, i = 0;
  7. do {
  8. printf("pow(3,%d) = %d\n", i, product);
  9. i++;
  10. product *= base;
  11. } while (i <= N);
  12. return 0;
  13. }
Case Hint Result Score Run Time Memory
0 同sample,n为正整数 Accepted 13 3 ms 256 KB
1 n==0 Accepted 2 2 ms 344 KB

练习2-18 求组合数

本题要求编写程序,根据公式Cnm=m!(nm)!n!算出从n个不同元素中取出m个元素(mn)的组合数。
建议定义和调用函数fact(n)计算n!,其中n的类型是int,函数类型是double
输入格式:
输入在一行中给出两个正整数mnmn),以空格分隔。
输出格式:
按照格式“result = 组合数计算结果”输出。题目保证结果在double类型范围内。
输入样例:

  1. 2 7

输出样例:

  1. result = 21

解题思路:实现阶乘函数 double fact(int n) 然后计算组合数即可。 :::tips 为什么阶乘函数要设置返回类型为 double ,因为阶乘结果很大, int 装不下从而出现溢出,而 double 类型数据范围更大。但是带来结果就是精度误差问题。而且题目最后要求输出整形,因此需要格式化控制浮点数的输出。 :::

  1. #include <stdio.h>
  2. double fact(int n) {
  3. double product = 1;
  4. for (int i = 2; i <= n; i++) {
  5. product *= i;
  6. }
  7. return product;
  8. }
  9. int main () {
  10. int m, n;
  11. scanf("%d %d", &m, &n);
  12. printf("result = %.0f\n", fact(n) / (fact(m) * fact(n - m))); // 保留 0 位小数
  13. return 0;
  14. }
Case Hint Result Score Run Time Memory
0 同sample,m严格小于n/2 Accepted 9 2 ms 204 KB
1 m==n/2 Accepted 2 2 ms 316 KB
2 m大于n/2,且n-m==1 Accepted 2 3 ms 184 KB
3 n==m Accepted 2 3 ms 196 KB

习题2-3 求平方与倒数序列的部分和

本题要求对两个正整数mnmn)编写程序,计算序列和 PTA编程—循环1 - 图9
输入格式:
输入在一行中给出两个正整数mnmn),其间以空格分开。
输出格式:
在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后六位。题目保证计算结果不超过双精度范围。
输入样例:

  1. 5 10

输出样例:

  1. sum = 355.845635

解题思路:公式已给出:直接求解 PTA编程—循环1 - 图10

  1. #include <stdio.h>
  2. int main () {
  3. int m, n;
  4. scanf("%d %d", &m, &n);
  5. double sum = 0.0;
  6. for (int i = m; i <= n; i++) {
  7. sum += i * i + 1.0 / i;
  8. }
  9. printf("sum = %.6lf", sum);
  10. return 0;
  11. }

运行结果:

Case Hint Result Run Time Memory
0 同sample Accepted

| 3 ms | 224 KB | | 1 | 最小边界 | Accepted

| 4 ms | 220 KB |

习题2-4 求交错序列前N项和

本题要求编写程序,计算交错序列 PTA编程—循环1 - 图11 的前N项之和。
输入格式:
输入在一行中给出一个正整数N。
输出格式:
在一行中输出部分和的值,结果保留三位小数。
输入样例:

  1. 5

输出样例:

  1. 0.917

解题思路:

  1. 分数:可知分子是递增,而分母是分子的两倍再减一。
  2. 符号:奇数项为正,偶数为负。 ```c

    include

int main () { int n; scanf(“%d”, &n); double sum = 0.0; // numerator:i, denominator:2i-1,sign=odd:1,even:-1 for (int i = 1, sign = 1; i <= n; i++) { sum += (double)i / (double)(2 i - 1) sign; sign *= -1; } printf(“%.3lf”, sum); return 0; }

  1. 运行结果:
  2. | Case | Hint | Result | Run Time | Memory |
  3. | --- | --- | --- | --- | --- |
  4. | 0 | sampleN是奇数 | Accepted
  5. | 3 ms | 356 KB |
  6. | 1 | N是偶数 | Accepted
  7. | 2 ms | 228 KB |
  8. | 2 | 最小奇数 | Accepted
  9. | 2 ms | 256 KB |
  10. | 3 | 最小偶数 | Accepted
  11. | 2 ms | 256 KB |
  12. <a name="de225c08"></a>
  13. # [习题2-5 求平方根序列前N项和](https://pintia.cn/problem-sets/12/problems/269)
  14. 本题要求编写程序,计算平方根序列 ![](https://cdn.nlark.com/yuque/__latex/e46594f8d2cb96fff2c8978f6802c0f3.svg#card=math&code=%5Csqrt%7B1%7D%2B%5Csqrt%7B2%7D%2B%5Csqrt%7B3%7D%2B%E2%8B%AF&height=19&id=ALA9c)的前N项之和。可包含头文件`math.h`,并调用`sqrt`函数求平方根。<br />**输入格式:**<br />输入在一行中给出一个正整数N。<br />**输出格式:**<br />在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后两位。题目保证计算结果不超过双精度范围。<br />**输入样例:**

10

  1. **输出样例:**

sum = 22.47

  1. **解题思路**:使用库函数直接求解 ![](https://cdn.nlark.com/yuque/__latex/6e78e7e3c2815832833cdee5a2dc13ee.svg#card=math&code=%5Csum_%7Bi%3D1%7D%5EN%5Csqrt%7Bi%7D&height=53&id=Fx2sk) 即可。
  2. ```c
  3. #include <stdio.h>
  4. #include <math.h>
  5. int main () {
  6. int n;
  7. scanf("%d", &n);
  8. double sum = 0.0;
  9. for (int i = 1; i <= n; i++) {
  10. sum += sqrt(i);
  11. }
  12. printf("sum = %.2lf", sum);
  13. return 0;
  14. }

运行结果:

Case Hint Result Run Time Memory
0 同sample Accepted

| 2 ms | 256 KB | | 1 | 最小N | Accepted

| 2 ms | 256 KB | | 2 | 较大N | Accepted

| 3 ms | 364 KB |

习题2-6 求阶乘序列前N项和

本题要求编写程序,计算序列 PTA编程—循环1 - 图12 的前N项之和。
输入格式:
输入在一行中给出一个不超过12的正整数N。
输出格式:
在一行中输出整数结果。
输入样例:

5

输出样例:

153

解题思路:不需要每次单独求 i! 可以直接在上一项阶乘的基础上继续乘 i 即可得到。

#include <stdio.h>

int main () {
    int n;
    scanf("%d", &n);
    int product = 1, sum = 1;
    for (int i = 2; i <= n; i++) {
        product *= i;
        sum += product;
    }
    printf("%d", sum);
    return 0;
}

运行结果:

Case Hint Result Run Time Memory
0 同sample Accepted

| 2 ms | 256 KB | | 1 | N最小 | Accepted

| 2 ms | 324 KB | | 2 | N最大 | Accepted

| 2 ms | 284 KB |

练习3-3 统计学生平均成绩与及格人数

本题要求编写程序,计算学生们的平均成绩,并统计及格(成绩不低于60分)的人数。题目保证输入与输出均在整型范围内。
输入格式:
输入在第一行中给出非负整数N,即学生人数。第二行给出N个非负整数,即这N位学生的成绩,其间以空格分隔。
输出格式:
按照以下格式输出:

average = 成绩均值
count = 及格人数

其中平均值精确到小数点后一位。
输入样例:

5
77 54 92 73 60

输出样例:

average = 71.2
count = 4

解题思路:统计即可,但是测试用例含有 0 ?那么由于分母不能为 0 ,所以单独判断输出。

#include <stdio.h>

int main () {
    int n;
    scanf("%d", &n);
    int score, sum = 0, pass = 0;
    if (0 >= n) {
        printf("average = 0.0\n");
        printf("count = 0");
        return 0;
    }
    for (int i = 0; i < n; i++) {
        scanf("%d", &score);
        sum += score;
        pass += score >= 60 ? 1 : 0;
    }
    printf("average = %.1f\n", sum * 1.0 / n);
    printf("count = %d", pass);
    return 0;
}

运行结果:

Case Hint Result Run Time Memory
0 sample等价,有大于、等于、小于60分 Accepted

| 3 ms | 384 KB | | 1 | 人数较多,但没有人及格 | Accepted

| 3 ms | 292 KB | | 2 | 没有学生 | Accepted

| 2 ms | 284 KB |

练习3-4 统计字符

本题要求编写程序,输入10个字符,统计其中英文字母、空格或回车、数字字符和其他字符的个数。
输入格式:
输入为10个字符。最后一个回车表示输入结束,不算在内。
输出格式:
在一行内按照

letter = 英文字母个数, blank = 空格或回车个数, digit = 数字字符个数, other = 其他字符个数

的格式输出。
输入样例:

aZ &
09 Az

输出样例:

letter = 4, blank = 3, digit = 2, other = 1
  1. 字符的输入,由于存在多行,普通的 scanffgets 都对多行有点吃力!因此由于题目数量给定为 10 那么直接使用 getchar() 是最方便的。 ```c

    include

    define MAXS 10

int main() { // char s[MAXS]; // scanf(“%[^\n]s”, s); // fgets(s, sizeof(s[0]) * MAXS, stdin); int letter = 0, blank = 0, digit = 0, other = 0; for (int i = 0; i < MAXS; i++) { char ch = getchar(); if ((‘A’ <= ch && ch <= ‘Z’) || (‘a’ <= ch && ch <= ‘z’)) { letter++; } else if (‘0’ <= ch && ch <= ‘9’) { digit++; } else if (‘ ‘ == ch || ‘\n’ == ch) { blank++; } else { other++; } } printf(“letter = %d, blank = %d, digit = %d, other = %d\n”, letter, blank, digit, other); return 0; }

**运行结果:**

| Case | Hint | Result | Run Time | Memory |
| --- | --- | --- | --- | --- |
| 0 | sample 四种类型全有,数字和字母取边界 | Accepted

 | 2 ms | 296 KB |
| 1 | 10个回车 | Accepted

 | 2 ms | 256 KB |
| 2 | 10个数字有重复 | Accepted

 | 2 ms | 384 KB |
| 3 | 10个字母有重复 | Accepted

 | 2 ms | 256 KB |
| 4 | 其他字符的边界 | Accepted

 | 2 ms | 256 KB |

<a name="IyzGj"></a>
# [练习3-5 输出闰年](https://pintia.cn/problem-sets/12/problems/276)
输出21世纪中截止某个年份以来的所有闰年年份。注意:闰年的判别条件是该年年份能被4整除但不能被100整除、或者能被400整除。<br />**输入格式:**<br />输入在一行中给出21世纪的某个截止年份。<br />**输出格式:**<br />逐行输出满足条件的所有闰年年份,即每个年份占一行。输入若非21世纪的年份则输出"Invalid year!"。若不存在任何闰年,则输出“None”。<br />**输入样例1:**

2048

**输出样例1:**

2004 2008 2012 2016 2020 2024 2028 2032 2036 2040 2044 2048

**输入样例2:**

2000

**输出样例2:**

Invalid year!

解题思路:

1. 21 世纪为 `2001-2100` 年,首先判断是否有效即可。
1. 闰年判断法:四年一闰,百年不闰,四百年再闰。设置 `flag = 0` 假设区间 `[2001, n]` 内不存在闰年。
1. 根据 `flag ?= 0` 判断输出 `Invalid!`
```c
#include <stdio.h>

int main () {
    int n;
    scanf("%d", &n);
    if (n <= 2000 || n > 2100) {  // 21 世纪的年份
        printf("Invalid year!");
        return 0;
    }
    int flag = 0;  // [2001, n] 内无润年
    for (int i = 2001; i <= n; i++) {
        if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {  // 四年一闰,百年不闰,四百年再闰
            printf("%d\n", i);
            flag = 1;
        }
    }
    if (0 == flag) {
        printf("None");
    }
    return 0;
}

运行结果:

Case Hint Result Run Time Memory
0 sample 1 正常的21世纪年份,正好截止到某闰年 Accepted

| 2 ms | 256 KB | | 1 | sample 2 小于2001 非21世纪的年份 | Accepted

| 2 ms | 364 KB | | 2 | 21世纪所有的年份 | Accepted

| 2 ms | 296 KB | | 3 | 超过21世纪上界的年份 | Accepted

| 2 ms | 364 KB | | 4 | 没有闰年 | Accepted

| 2 ms | 256 KB |

习题3-4 统计学生成绩

本题要求编写程序读入N个学生的百分制成绩,统计五分制成绩的分布。百分制成绩到五分制成绩的转换规则:

  • 大于等于90分为A;
  • 小于90且大于等于80为B;
  • 小于80且大于等于70为C;
  • 小于70且大于等于60为D;
  • 小于60为E。

输入格式:
输入在第一行中给出一个正整数N(≤1000),即学生人数;第二行中给出N个学生的百分制成绩,其间以空格分隔。
输出格式:
在一行中输出A、B、C、D、E对应的五分制成绩的人数分布,数字间以空格分隔,行末不得有多余空格。
输入样例:

7
77 54 92 73 60 65 69

输出样例:

1 0 2 3 1

解题思路:同上,只不过换成 IO 而已。

#include <stdio.h>
int main() {
    int n, score, A = 0, B = 0, C = 0, D = 0, E = 0;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &score);
        if (score >= 90) {
            A++;
        } else if (score >= 80) {
            B++;
        } else if (score >= 70) {
            C++;
        } else if (score >= 60) {
            D++;
        } else {
            E++;
        }
    }
    printf("%d %d %d %d %d", A, B, C, D, E);
    return 0;
}

#include <stdio.h>
int main() {
    int n, score, A = 0, B = 0, C = 0, D = 0, E = 0;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &score);
        switch (score / 10) {
            case 10:
            case 9:
                A++; break;
            case 8:
                B++;break;
            case 7:
                C++;break;
            case 6:
                D++;break;
            default:
                E++;
        }
    }
    printf("%d %d %d %d %d", A, B, C, D, E);
    return 0;
}
Case Hint Result Run Time Memory
0 同sample,有分数段为0 Accepted

| 3 ms | 296 KB | | 1 | 最小N,最小分数 | Accepted

| 3 ms | 376 KB | | 2 | 最大随机N,各个分数段全有,有最大100分 | Accepted

| 3 ms | 296 KB |