C 语言程序设计 CAP 学习记录

第 1 章:引入(20180807)

简易找零程序

这是老师在上课时所给的程序。

1
2
3
4
5
6
7
8
9
10
#include 
int main()
{
int price = 0;
printf("请输入金额(元):");
scanf("%d", &price);
int change = 100 - price;
printf("找您%d元。\n", change);
return 0;
}

经观察发现,该程序有若干不足,比如无法计算零头、无法确认所给票面金额是否足够,收银商品额固定为 100 元。

改进如下:

  1. 修改数值类型为浮点数
  2. 增增加获取商品金额数据
  3. 增加票面金额与商品金额比较

#include <stdio.h>
int main()
{
// 初始化
float a;
float b;
// 获取数据
printf (“请输入商品金额(元):”);
scanf(“%f”,&a);
printf (“请输入票面金额(元):”);
scanf(“%f”,&b);
// 处理输出结果
float c=b-a;
if(c<0)
{
printf (“当前支付金额不足以购买商品。”);
}
else
{
printf (“找零 %.2f 元。”,c);
}
// 结束
return 0;
}```

第 2 章:计算(20180808)

逆序的三位数逆 (10 分)

题目

程序每次读入一个正三位数,然后输出逆序的数字。注意,当输入的数字含有结尾的 0 时,输出不应带有前导的 0。比如输入 700,输出应该是 7。

提示:

对一个三位数数 x,做 x%10 可以得到它的个位数,做 x/100 可以得到它的百位数,十位数则通过 / 和 % 两个运算的结合可以得到。

输入格式:

你的程序每次读到一个 3 位的正整数。

输出格式:

输出逆序的数。

输入样例:

163

输出样例:

361

解题

因为题目所给出要求 700 倒序不能为 007 而应该是 7,所以就不能考虑获取每一位数字后重新排列,而应该时获取倒序后的整体数值。其中的难点就在于如何分别获取每位数上的具体数值。

我的解答

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main()
{
//初始化
int a=0;
//获取数值
scanf("%d", &a);
//改变顺序并输出结果
printf("%d\n",a%10*100+(a-a%10-a/100*100)+a/100);
//结束
return 0;
}

第 3 章:判断(20180809)

时间换算(10 分)

题目

UTC 是世界协调时,BJT 是北京时间,UTC 时间相当于 BJT 减去 8。现在,你的程序要读入一个整数,表示 BJT 的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于 10,则没有千位部分;如果小时是 0,则没有百位部分;如果小时不是 0 而分小于 10 分,需要保留十位上的 0;如果小时是 0 而分小于 10 分的,则不需要保留十位上的 0。如 1124 表示 11 点 24 分,而 905 表示 9 点 5 分,36 表示 0 点 36 分,7 表示 0 点 7 分。

有效的输入范围是 0 到 2359,即你的程序不可能从测试服务器读到 0 到 2359 以外的输入数据。

你的程序要输出这个时间对应的 UTC 时间,输出的格式和输入的相同,即输出一个整数,表示 UTC 的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于 10,则没有千位部分;如果小时是 0,则没有百位部分;如果小时不是 0 而分小于 10 分,需要保留十位上的 0;如果小时是 0 而分小于 10 分的,则不需要保留十位上的 0。

提醒:

要小心跨日的换算。

输入格式:

一个整数,表示 BJT 的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于 10,则没有千位部分;如果小时是 0,则没有百位部分;如果小时不是 0 而分小于 10 分,需要保留十位上的 0;如果小时是 0 而分小于 10 分的,则不需要保留十位上的 0。

输出格式:

一个整数,表示 UTC 的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于 10,则没有千位部分;如果小时是 0,则没有百位部分;如果小时不是 0 而分小于 10 分,需要保留十位上的 0;如果小时是 0 而分小于 10 分的,则不需要保留十位上的 0。

输入样例:

803

输出样例:

3

解题

本题问题所在即为时差 8 小时需要在对应的格式中转换为 800,并注意加减时差跨天的时差所在。

我的解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stido.h>
int main()
{
//初始化
int BJT=0;
int UTC=0;
//获取数据
scanf("%d", &BJT);
//处理时差
if(BJT >= 800)//判断时差是否隔天
{
UTC=BJT-800;
}
else
{
UTC=BJT+2400-800;
}
//输出结果
printf("%d",UTC);
//结束
return 0;
}

第 4 章:循环(20180810)

奇偶个数(10 分)

题目

你的程序要读入一系列正整数数据,输入 - 1 表示输入结束,-1 本身不是输入的数据。程序输出读到的数据中的奇数和偶数的个数。

输入格式:

一系列正整数,整数的范围是(0,100000)。如果输入 - 1 则表示输入结束。

输出格式:

两个整数,第一个整数表示读入数据中的奇数的个数,第二个整数表示读入数据中的偶数的个数。两个整数之间以空格分隔。

输入样例:

9 3 4 2 5 7 -1 

输出样例:

4 2

解题

最初版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
int main()
{
int num=0;
int s=0;
int d=0;
int j=0;

do
{scanf("%d",&num);
if (num == -1)
{
break;
}
else
{
j = num%2;
if(j==0)
{
d++;
}
else
{
s++;
}
}
}
while(num != -1);
printf("%d %d", s, d);
return 0;
}

虽然程序程序可以正常运行并输出正确的结果,但不难看出,代码中的 do-while 循环其实判断是否重复的代码并没有起到作用,经思考后优化如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
int main()
{
//初始化
int num=0;
int s=0;
int d=0;
//获取数值
while(scanf("%d",&num))
{
//终止符判断
if (num == -1)
{
break;
}
//偶数计数
if(num%2==0)
{
d++;
}
//奇数计数
else
{
s++;
}
}
//输出结果
printf("%d %d", s, d);
//结束
return 0;
}