任务1
- 源代码task1.c
点击查看代码
#include <stdio.h>
char score_to_grade(int score); // 函数声明
int main() {
int score;
char grade;
while(scanf("%d", &score) != EOF) {
grade = score_to_grade(score); // 函数调用
printf("分数: %d, 等级: %c\n\n", score, grade);
}
return 0;
}
// 函数定义
char score_to_grade(int score) {
char ans;
switch(score/10) {
case 10:
case 9: ans = 'A'; break;
case 8: ans = 'B'; break;
case 7: ans = 'C'; break;
case 6: ans = 'D'; break;
default: ans = 'E';
}
return ans;
}
-
运行测试截图
-
问题1:把分数转化成等级
-
问题2:1.双引号是字符串常量;ans是char字符变量,字符要用单引号,否则会类型不匹配。
2.缺少break;,会发生case穿透。匹配成功后继续执行所有分支,结果错乱。
任务二
- 源代码
点击查看代码
#include <stdio.h>
int sum_digits(int n); // 函数声明
int main() {
int n;
int ans;
while(printf("Enter n: "), scanf("%d", &n) != EOF) {
ans = sum_digits(n); // 函数调用
printf("n = %d, ans = %d\n\n", n, ans);
}
return 0;
}
// 函数定义
int sum_digits(int n) {
int ans = 0;
while(n != 0) {
ans += n % 10;
n /= 10;
}
return ans;
}
- 运行截图
- 问题1:计算并返回一个非负整数n的各数字之和。
- 问题2:能。对于正整数的输入,结果完全一致。思维区别:原来的实现方式按照"顺序处理",每次把结果累加到ans中去,直到数字变为0.这是一种状态不断更新的过程。
新的实现方式是"自顶而上,分而治之",是递归法。不断调用,直至达到终止条件,才开始意义返回相加。
任务三
- 源代码
点击查看代码
#include <stdio.h>
int power(int x, int n); // 函数声明
int main() {
int x, n;
int ans;
while(printf("Enter x and n: "), scanf("%d%d", &x, &n) != EOF) {
ans = power(x, n); // 函数调用
printf("n = %d, ans = %d\n\n", n, ans);
}
return 0;
}
// 函数定义
int power(int x, int n) {
int t;
if(n == 0)
return 1;
else if(n % 2)
return x * power(x, n-1);
else {
t = power(x, n/2);
return t*t;
}
}
-
运行截图
-
问题1:
计算x^n(n=>0) -
问题2:是递归函数。递归出口:n=0,x^0=1.
数学模型:
问题3:1.逻辑上仍然正确。数学上等价,只是写法实现方式改变了。
2.原版只调用一次power(x,n/2),保存结果再自乘,子问题只算一遍。原版power(3,16)有4次子问题求值。
修改版连续调用两次power(x,n/2),同一个子问题连续计算两遍,每一次计算量翻倍。修改版调用了47次。
任务四
- 源代码
点击查看代码
#include <stdio.h>
// 函数原型声明
int classify_triangle(int a, int b, int c);
int main() {
int a, b, c;
// 支持多组输入,当成功读取三个整数时继续循环
while (scanf("%d %d %d", &a, &b, &c) == 3) {
int result = classify_triangle(a, b, c);
// 基于返回值判断,配合 if 或 switch 输出三角形类型
switch (result) {
case 0:
printf("不能构成\n");
break;
case 1:
printf("普通\n");
break;
case 2:
printf("等边\n");
break;
case 3:
printf("等腰\n");
break;
case 4:
printf("直角\n");
break;
default:
printf("未知类型\n");
}
}
return 0;
}
// 判断三角形类型函数实现
int classify_triangle(int a, int b, int c) {
// 1. 判断是否能构成三角形(三边均为正,且满足两边之和大于第三边)
// 排序后只需判断较短两边之和是否大于最长边
int temp;
if (a <= 0 || b <= 0 || c <= 0) {
return 0; // 不能构成
}
// 简单排序,确保 a <= b <= c
if (a > b) { temp = a; a = b; b = temp; }
if (b > c) { temp = b; b = c; c = temp; }
if (a > b) { temp = a; a = b; b = temp; }
if (a + b <= c) {
return 0; // 不能构成
}
// 2. 判断具体类型
// 直角三角形判断(勾股定理 a^2 + b^2 == c^2)
// 注意:题目返回值中直角为4,若有特殊叠加(如等腰直角),通常优先返回直角或按题目隐含优先级
if (a * a + b * b == c * c) {
return 4; // 直角
}
// 等边三角形
if (a == b && b == c) {
return 2; // 等边
}
// 等腰三角形(恰好两边相等)
if (a == b || b == c || a == c) {
return 3; // 等腰
}
// 普通三角形
return 1; // 普通
}
- 运行截图
任务五
- 运行代码
点击查看代码
#include <stdio.h>
int func(int n, int m); // 函数声明
int main() {
int n, m;
int ans;
while(scanf("%d%d", &n, &m) != EOF) {
ans = func(n, m); // 函数调用
printf("n = %d, m = %d, ans = %d\n\n", n, m, ans);
}
return 0;
}
// 函数定义
// 方式一:迭代方式实现
int func(int n, int m) {
// 边界条件:m > n 或 m < 0 时,组合数为 0
if (m < 0 || m > n) {
return 0;
}
//C(n, m) = C(n, n-m),取较小的 m 减少循环次数
if (m > n - m) {
m = n - m;
}
// 边界条件:m = 0 或 m = n 时,组合数为 1
if (m == 0) {
return 1;
}
long long res = 1;
// 使用公式:C(n, m) = n(n-1)...(n-m+1) / m(m-1)...1
for (int i = 1; i <= m; i++) {
res = res * (n - m + i) / i;
}
return (int)res;
}
// 方式二:递归方式
/*
int func(int n, int m) {
// 边界条件(递归出口):根据测试结果 m>n 返回0,m=0或m=n返回1
if (m < 0 || m > n) {
return 0;
}
if (m == 0 || m == n) {
return 1;
}
// 递归调用
return func(n - 1, m) + func(n - 1, m - 1);
}
*/
- 运行截图
任务六
- 源代码
点击查看代码
#include <stdio.h>
int gcd(int a,int b,int c);
int main() {
int a, b, c;
int ans;
while(scanf("%d%d%d", &a, &b, &c) != EOF) {
ans = gcd(a, b, c); // 函数调用
printf("最大公约数: %d\n\n", ans);
}
return 0;
}
int gcd(int a,int b,int c){
int min=a;
if(b<min)min=b;
if(c<min)min=c;
int i;
for(i=min;i>=1;i--)
{
if(a%i==0&&b%i==0&&c%i==0)
return i;
}
}
- 运行测试截图
任务七
- 源代码
点击查看代码
#include <stdio.h>
#include <stdlib.h>
// 函数声明
void print_charman(int n);
int main() {
int n;
printf("Enter n: ");
scanf("%d", &n);
print_charman(n); // 函数调用
return 0;
}
// 函数print_charman定义
void print_charman(int n) {
int i, j, k;
// 外层循环控制行数,从 n 递减到 1
for (i = n; i >= 1; i--) {
// 打印头部 " 0 "
// 每一层前面先打印缩进空格。缩进量随着行数递减而增加。
// 观察效果,大概每次缩进2个字符宽度
for (k = 0; k < (n - i); k++) {
printf(" ");
}
for (j = 0; j < i; j++) {
printf(" 0 "); // 注意 0 前后的空格以匹配预览图
}
printf("\n");
// 打印身体 "<H>"
for (k = 0; k < (n - i); k++) {
printf(" ");
}
for (j = 0; j < i; j++) {
printf(" <H> ");
}
printf("\n");
// 打印腿部 " I "
for (k = 0; k < (n - i); k++) {
printf(" ");
}
for (j = 0; j < i; j++) {
printf(" I ");
}
printf("\n");
}
}
- 运行截图