时间相加是编程中常见的基础问题,主要考察对时间进位规则的理解和实现。在实际开发中,类似场景出现在计时器累计、日志时间统计等场景。题目要求将两个由时分秒组成的时间相加,并正确处理进位问题。
核心需求:
c复制#include <stdio.h>
int main(){
int AH,AM,AS; // 时间A的时、分、秒
int BH,BM,BS; // 时间B的时、分、秒
int S,H,M; // 结果秒、时、分
scanf("%d %d %d %d %d %d",&AH,&AM,&AS,&BH,&BM,&BS);
// 原始相加
S=AS+BS;
M=AM+BM;
H=AH+BH;
// 处理秒进位
if(S>59){
S=S-60;
M=M+1;
}
// 处理分进位
if(M>59){
M=M-60;
H=H+1;
}
printf("%d %d %d",H,M,S);
return 0;
}
进位处理顺序:必须先处理秒进位,再处理分进位。如果顺序颠倒,可能导致进位不完整。
边界情况:
输入验证:
if(AS<0 || AS>59) return -1; 等验证提示:在嵌入式系统开发中,类似的时间处理通常使用结构体封装,提高代码可读性。
成绩转换是教育系统中常见功能,将百分制分数转换为等级制。业务规则如下:
| 分数区间 | 等级 |
|---|---|
| 90~100 | A |
| 80~89 | B |
| 70~79 | C |
| 60~69 | D |
| 0~59 | E |
c复制if(t>=90 && t<=100){
grade = 'A';
}else if(t>=80 && t<90){
grade = 'B';
} // ...其他条件
c复制char grade_table[] = {'E','E','E','E','E','E','D','C','B','A','A'};
grade = grade_table[t/10];
c复制#include <stdio.h>
int main(){
int t;
char grade;
scanf("%d",&t);
// 输入验证
if(t>100||t<0){
printf("Score is error!");
return 0;
}
// 等级判断
if(t>=90){
grade = 'A';
}else if(t>=80){
grade = 'B';
}else if(t>=70){
grade = 'C';
}else if(t>=60){
grade = 'D';
}else {
grade = 'E';
}
printf("%c\n",grade);
return 0;
}
闰年规则:
c复制int is_leap_year(int year) {
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
使用数组存储各月天数,注意:
c复制int month_days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
c复制#include <stdio.h>
int is_leap_year(int year) {
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
int main() {
int y, m, d;
scanf("%d %d %d", &y, &m, &d);
int month_days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(is_leap_year(y)) month_days[2] = 29;
int total_days = d; // 直接初始化天数
for (int i = 1; i < m; i++) {
total_days += month_days[i];
}
printf("%d", total_days);
return 0;
}
i < m 而非 i <= mtotal_days 应初始化为 d 而非 0阶乘尾随零的数量由因子5的个数决定,因为:
计算n!中5的因子数公式:
code复制zeros = ⌊n/5⌋ + ⌊n/25⌋ + ⌊n/125⌋ + ...
c复制#include <stdio.h>
int count_trailing_zeros(int N) {
int count = 0;
while (N > 0) {
N /= 5;
count += N;
}
return count;
}
int main() {
int n;
while(scanf("%d", &n) == 1){
printf("%d\n", count_trailing_zeros(n));
}
return 0;
}
时间复杂度:O(log₅N)
测试用例:
注意:对于n=100000,结果应为24999,验证算法正确性
完全数是指等于其真因子之和的数,例如:
已知性质:
c复制for(int i=1; i<N; i++){
int sum = 0;
for(int j=1; j<i; j++){
if(i%j == 0) sum += j;
}
if(sum == i) printf("%d\n",i);
}
c复制#include <stdio.h>
#include <math.h>
int main() {
int N;
scanf("%d", &N);
for (int i = 2; i <= N; i++) {
int sum = 1; // 1是所有数的因子
for (int j = 2; j <= sqrt(i); j++) {
if (i % j == 0) {
sum += j;
if(j != i/j) sum += i/j; // 配对因子
}
}
if (sum == i) {
printf("%d\n", i);
}
}
return 0;
}
| 方法 | 时间复杂度 | 适用场景 |
|---|---|---|
| 暴力 | O(N²) | 小范围N |
| 优化 | O(N√N) | 中等N |
| 数论 | O(1) | 已知完全数 |
给定三个数字a,b,c,构造abc和cba两个三位数:
数字构造:
c复制int abc = a*100 + b*10 + c;
int cba = c*100 + b*10 + a;
乘积处理:
c复制#include <stdio.h>
int main() {
int a, b, c;
while (scanf("%d %d %d", &a, &b, &c) == 3) {
int abc = a * 100 + b * 10 + c;
int cba = c * 100 + b * 10 + a;
long long product = (long long)abc * cba;
int count = 0;
long long temp = product;
do {
int digit = temp % 10;
if (digit == a || digit == b || digit == c) {
count++;
}
temp /= 10;
} while (temp != 0);
printf("%lld %d\n", product, count);
}
return 0;
}
| 输入 | 乘积 | 匹配数 | 说明 |
|---|---|---|---|
| 1 1 1 | 12321 | 2 | 重复数字测试 |
| 9 9 9 | 998001 | 0 | 边界值测试 |
| 1 2 3 | 39483 | 2 | 常规测试 |
在实际编码竞赛中,这类题目考察的是对数字处理的熟练度和边界条件处理能力。我建议在开发时添加更多的断言检查,确保每个中间步骤的正确性。