- 练习2-12 输出华氏-摄氏温度转换表">练习2-12 输出华氏-摄氏温度转换表
- 练习2-13 求N分之一序列前N项和">练习2-13 求N分之一序列前N项和
- 练习2-14 求奇数分之一序列前N项和
- 练习2-15 求简单交错序列前N项和">练习2-15 求简单交错序列前N项和
- 练习2-17 生成3的乘方表">练习2-17 生成3的乘方表
- 练习2-18 求组合数">练习2-18 求组合数
- 习题2-3 求平方与倒数序列的部分和">习题2-3 求平方与倒数序列的部分和
- 习题2-4 求交错序列前N项和">习题2-4 求交错序列前N项和
- include
- 习题2-6 求阶乘序列前N项和">习题2-6 求阶乘序列前N项和
- 练习3-3 统计学生平均成绩与及格人数">练习3-3 统计学生平均成绩与及格人数
- 练习3-4 统计字符">练习3-4 统计字符
- include
- define MAXS 10
- 习题3-4 统计学生成绩">习题3-4 统计学生成绩
练习2-12 输出华氏-摄氏温度转换表
输入2个正整数lower
和upper
(lower
≤upper
≤100),请输出一张取值范围为[lower
,upper
]、且每次增加2华氏度的华氏-摄氏温度转换表。
温度转换的计算公式:C=5×(F−32)/9,其中:C表示摄氏温度,F表示华氏温度。
输入格式:
在一行中输入2个整数,分别表示lower
和upper
的值,中间用空格分开。
输出格式:
第一行输出:”fahr celsius”
接着每行输出一个华氏温度fahr(整型)与一个摄氏温度celsius(占据6个字符宽度,靠右对齐,保留1位小数)。
若输入的范围不合法,则输出”Invalid.”。
输入样例1:
32 35
输出样例1:
fahr celsius
32 0.0
34 1.1
输入样例2:
40 30
输出样例2:
Invalid.
解题思路:循环的范围就是 [lower
,upper
],变量每次自增 2
即可。
#include <stdio.h>
int main () {
int m, n;
scanf("%d %d", &m, &n);
// 1.判断合法性
if (m > n) {
printf("Invalid.");
return 0;
}
printf("fahr celsius\n");
// 2.步长位2循环输出
for (; m <= n; m += 2) {
float celsius = 5 * (m - 32) / 9.0;
printf("%d%6.1f\n", m, celsius);
}
return 0;
}
运行结果:
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位。题目保证计算结果不超过双精度范围。
输入样例:
6
输出样例:
sum = 2.450000
解题思路:根据题意可得通项公式为 ,而题目所求即为
,因此使用循环即可。
#include <stdio.h>
int main() {
int N;
scanf("%d", &N);
double sum = 0.0;
for (int i = 1; i <= N; i++) {
sum += 1.0 / i;
}
printf("sum = %.6f\n", sum);
return 0;
}
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位。题目保证计算结果不超过双精度范围。
输入样例:
23
输出样例:
sum = 2.549541
解题思路:根据题意可得通项公式为 ,而题目所求即为
,因此使用循环即可。
#include <stdio.h>
int main() {
int N;
scanf("%d", &N);
double sum = 0.0;
for (int i = 1; N > 0; i += 2) {
sum += 1.0 / i;
N--;
}
printf("sum = %.6f\n", sum);
return 0;
}
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,精确到小数点后三位。题目保证计算结果不超过双精度范围。
输入样例:
10
输出样例:
sum = 0.819
解题思路:根据题意可得通项公式为 ,而题目所求即为
,因此使用循环即可。
#include <stdio.h>
int main() {
int N;
scanf("%d", &N);
double sum = 0.0;
for (int i = 1, sign = 1; N > 0; i += 3, sign *= -1) {
sum += 1.0 / i * sign;
N--;
}
printf("sum = %.3f\n", sum);
return 0;
}
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的乘方表,输出的值。可调用幂函数计算3的乘方。
输入格式:
输入在一行中给出一个非负整数n。
输出格式:
按照幂的递增顺序输出n+1行,每行格式为“pow(3,i) = 3的i次幂的值”。题目保证输出数据不超过长整型整数的范围。
输入样例:
3
输出样例:
pow(3,0) = 1
pow(3,1) = 3
pow(3,2) = 9
pow(3,3) = 27
解题思路:本题最重要的是实现 pow(3, n)
函数,最笨的方式就是使用累乘。但是实际上题目要求输出连续的乘法结果,即有 ,因此在输出下一个乘方时,我们不必再进行
n
次累乘,而是直接在前一项基础上再 ×3
:::tips
注意下方代码循环判断条件!当 n = 0
时也要输出,因此使用 do-while
循环更好。
:::
#include <stdio.h>
#define base 3
int main() {
int N;
scanf("%d", &N);
int product = 1, i = 0;
do {
printf("pow(3,%d) = %d\n", i, product);
i++;
product *= base;
} while (i <= N);
return 0;
}
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!(n−m)!n!算出从n个不同元素中取出m个元素(m≤n)的组合数。
建议定义和调用函数fact(n)
计算n!
,其中n
的类型是int
,函数类型是double
。
输入格式:
输入在一行中给出两个正整数m和n(m≤n),以空格分隔。
输出格式:
按照格式“result = 组合数计算结果”输出。题目保证结果在double
类型范围内。
输入样例:
2 7
输出样例:
result = 21
解题思路:实现阶乘函数 double fact(int n)
然后计算组合数即可。
:::tips
为什么阶乘函数要设置返回类型为 double
,因为阶乘结果很大, int
装不下从而出现溢出,而 double
类型数据范围更大。但是带来结果就是精度误差问题。而且题目最后要求输出整形,因此需要格式化控制浮点数的输出。
:::
#include <stdio.h>
double fact(int n) {
double product = 1;
for (int i = 2; i <= n; i++) {
product *= i;
}
return product;
}
int main () {
int m, n;
scanf("%d %d", &m, &n);
printf("result = %.0f\n", fact(n) / (fact(m) * fact(n - m))); // 保留 0 位小数
return 0;
}
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 求平方与倒数序列的部分和
本题要求对两个正整数m和n(m≤n)编写程序,计算序列和 。
输入格式:
输入在一行中给出两个正整数m和n(m≤n),其间以空格分开。
输出格式:
在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后六位。题目保证计算结果不超过双精度范围。
输入样例:
5 10
输出样例:
sum = 355.845635
解题思路:公式已给出:直接求解 。
#include <stdio.h>
int main () {
int m, n;
scanf("%d %d", &m, &n);
double sum = 0.0;
for (int i = m; i <= n; i++) {
sum += i * i + 1.0 / i;
}
printf("sum = %.6lf", sum);
return 0;
}
运行结果:
Case | Hint | Result | Run Time | Memory |
---|---|---|---|---|
0 | 同sample | Accepted |
| 3 ms | 224 KB | | 1 | 最小边界 | Accepted
| 4 ms | 220 KB |
习题2-4 求交错序列前N项和
本题要求编写程序,计算交错序列 的前N项之和。
输入格式:
输入在一行中给出一个正整数N。
输出格式:
在一行中输出部分和的值,结果保留三位小数。
输入样例:
5
输出样例:
0.917
解题思路:
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; }
运行结果:
| Case | Hint | Result | Run Time | Memory |
| --- | --- | --- | --- | --- |
| 0 | sample,N是奇数 | Accepted
| 3 ms | 356 KB |
| 1 | N是偶数 | Accepted
| 2 ms | 228 KB |
| 2 | 最小奇数 | Accepted
| 2 ms | 256 KB |
| 3 | 最小偶数 | Accepted
| 2 ms | 256 KB |
<a name="de225c08"></a>
# [习题2-5 求平方根序列前N项和](https://pintia.cn/problem-sets/12/problems/269)
本题要求编写程序,计算平方根序列 的前N项之和。可包含头文件`math.h`,并调用`sqrt`函数求平方根。<br />**输入格式:**<br />输入在一行中给出一个正整数N。<br />**输出格式:**<br />在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后两位。题目保证计算结果不超过双精度范围。<br />**输入样例:**
10
**输出样例:**
sum = 22.47
**解题思路**:使用库函数直接求解  即可。
```c
#include <stdio.h>
#include <math.h>
int main () {
int n;
scanf("%d", &n);
double sum = 0.0;
for (int i = 1; i <= n; i++) {
sum += sqrt(i);
}
printf("sum = %.2lf", sum);
return 0;
}
运行结果:
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项和
本题要求编写程序,计算序列 的前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
- 字符的输入,由于存在多行,普通的
scanf
和fgets
都对多行有点吃力!因此由于题目数量给定为10
那么直接使用getchar()
是最方便的。 ```cinclude
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 |