1. 东华OJ基础题69-73题解析
作为一名计算机专业的老码农,我深知编程基础练习的重要性。东华OJ平台的基础题目是很多同学入门算法的必经之路,今天我就来详细拆解69-73这五道基础题目。这些题目看似简单,但其中蕴含的编程思维和技巧对打牢基础至关重要。
这五道题涵盖了字符串处理、数学运算、数组操作等基础编程知识点。在实际教学中发现,很多同学虽然能通过样例测试,但对题目本质的理解和代码优化往往不够深入。接下来我将从题目分析、解题思路、代码实现到优化技巧,全方位解析每道题目。
2. 题目69:字符串逆序输出
2.1 题目要求分析
题目要求输入一个字符串,将其逆序输出。例如输入"hello",输出"olleh"。这道题考察的是基本的字符串操作能力。
2.2 基础解法
最直观的方法是使用循环从后向前遍历字符串:
c复制#include <stdio.h>
#include <string.h>
int main() {
char str[100];
gets(str);
int len = strlen(str);
for(int i = len-1; i >=0; i--) {
printf("%c", str[i]);
}
return 0;
}
2.3 优化方案
更简洁的写法是利用递归或标准库函数:
c复制// 使用递归
void reversePrint(char* str) {
if(*str) {
reversePrint(str+1);
putchar(*str);
}
}
// 使用库函数
printf("%s", strrev(str));
注意:在实际OJ环境中,strrev函数可能不被支持,建议使用第一种方法
2.4 常见错误
- 数组越界:忘记字符串以'\0'结尾,循环条件写错
- 输入处理:使用scanf("%s")会忽略空格,gets更合适但要注意缓冲区大小
- 空字符串处理:没有考虑输入为空的情况
3. 题目70:数字统计
3.1 问题描述
输入一个整数n,统计1到n之间数字'2'出现的次数。例如n=20,输出3(2,12,20)。
3.2 算法设计
暴力解法是遍历每个数字逐位检查:
c复制int count = 0;
for(int i=1; i<=n; i++) {
int num = i;
while(num > 0) {
if(num % 10 == 2) count++;
num /= 10;
}
}
3.3 数学优化
更高效的解法是分析数字规律,按位统计:
c复制int count = 0;
for(int base=1; base<=n; base*=10) {
int higher = n/(base*10);
int lower = n%base;
int current = (n/base)%10;
count += higher * base;
if(current > 2) count += base;
else if(current == 2) count += lower + 1;
}
3.4 性能对比
当n=1e8时:
- 暴力解法:约5秒
- 数学解法:<0.01秒
4. 题目71:矩阵转置
4.1 题目要求
给定一个n×n的矩阵,实现原地转置(不使用额外空间)。
4.2 关键思路
沿主对角线交换元素:
c复制for(int i=0; i<n; i++) {
for(int j=i+1; j<n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
4.3 边界情况
- 奇数阶矩阵:中间元素不需要处理
- 空矩阵:需要特殊判断
- 非方阵:本题限定为方阵,但实际中需要考虑行列不等的情况
5. 题目72:最大公约数
5.1 问题描述
输入两个正整数,求它们的最大公约数。
5.2 算法实现
经典的欧几里得算法:
c复制int gcd(int a, int b) {
return b==0 ? a : gcd(b, a%b);
}
5.3 迭代版本
避免递归栈溢出:
c复制int gcd(int a, int b) {
while(b) {
int temp = a % b;
a = b;
b = temp;
}
return a;
}
5.4 扩展应用
最小公倍数计算:
c复制int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
6. 题目73:素数判断
6.1 题目要求
判断给定的正整数是否为素数。
6.2 基础解法
试除法:
c复制int isPrime(int n) {
if(n <= 1) return 0;
for(int i=2; i*i<=n; i++) {
if(n%i == 0) return 0;
}
return 1;
}
6.3 优化方案
- 排除偶数:除2外所有偶数都不是素数
- 预生成素数表:适用于多次查询
- Miller-Rabin算法:概率性检测大素数
优化后的代码:
c复制int isPrime(int n) {
if(n <= 1) return 0;
if(n == 2) return 1;
if(n%2 == 0) return 0;
for(int i=3; i*i<=n; i+=2) {
if(n%i == 0) return 0;
}
return 1;
}
7. 综合技巧与实战建议
7.1 调试技巧
- 边界测试:0、1、最大值等特殊情况
- 中间输出:在关键步骤打印变量值
- 代码复用:将常用功能封装成函数
7.2 性能优化
- 避免重复计算:如素数判断时保存计算结果
- 使用更优算法:如数字统计问题的数学解法
- 减少I/O操作:批量处理输入输出
7.3 编码规范
- 变量命名:使用有意义的名称
- 适当注释:解释复杂逻辑
- 错误处理:考虑非法输入情况
在实际刷题过程中,建议先理解题目本质,再动手编码。完成基础解法后,思考是否有优化空间。这些基础题目虽然简单,但深入理解后对提升编程能力大有裨益。