实验3

task1

代码

#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: 功能:函数  score_to_grade  的功能是根据输入的整数分数  score ,通过对  score/10  的判断,将分数转换为对应的等级字符(如  'A' 、 'B'  等)并返回。形参类型: int (接收整数分数)。

返回值类型: char (返回表示等级的字符)。

问题2:1. 字符常量表示错误:

原代码使用单引号  'A'  表示字符常量,修改后用双引号  "A" (字符串),而  ans  是  char  类型,不能赋值字符串,会导致编译错误。
2. 缺少  break  语句:
每个  case  分支后未添加  break ,会引发“穿透”现象。例如输入  95 ( score/10  为  9 ),执行完  case 9  后会继续执行  case 8  等后续代码,最终结果错误。
3.  case 10  逻辑错误:
修改后的代码中, case 10  分支未处理(无赋值语句),且未添加  break ,会穿透到  case 9 ,导致逻辑混乱。

 

task2

代码

#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:函数`sum_digits`的功能是计算输入整数`n`的各位数字之和。

问题2:原因:新定义的递归版本中,若 n < 10 直接返回 n (处理个位);否则通过 sum_digits(n/10) + n%10 递归分解 n ,先处理高位再累加当前位,与原循环逐位分解累加的逻辑一致。

算法思维区别:原实现是迭代循环,通过循环逐次处理每一位;新实现是递归,利用函数自身调用分解问题,二者本质都是逐位提取数字并求和,仅实现方式(迭代 vs 递归)不同。

 

task3

 

代码:

#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:函数  power  的功能是计算并返回参数  x  的  n  次幂(即  x^n )。通过递归方式,根据  n  的不同取值(0、奇数、偶数),采用不同的计算逻辑实现幂运算。

问题2:

函数  power  是递归函数,因为其在函数体内调用了自身。递归模式对应的数学公式模型如下:

- 当 n = 0 时: x^n = 1

- 当 n 为奇数时: x^n = x \times x^{n-1}

- 当 n 为偶数时: x^n = \left( x^{n/2} \right)^2

 

task4

代码:

#include <stdio.h>
#include <math.h>

// 判断素数函数
int is_prime(int n) {
    if (n <= 1) return 0;
    for (int i = 2; i <= sqrt(n); i++) {
        if (n % i == 0) {
            return 0;
        }
    }
    return 1;
}

int main() {
    int count = 0;
    printf("100以内的孪生素数:\n");
    for (int n = 3; n <= 97; n += 2) {  // 遍历可能的n值,步长2(偶数无需判断)
        if (is_prime(n) && is_prime(n + 2)) {
            printf("%d %d\n", n, n + 2);
            count++;
        }
    }
    printf("100以内的孪生素数共有%d个.\n", count);
    return 0;
}

 

结果:

 

 

task5

代码:

#include <stdio.h>
#include <stdlib.h>

#define MAX_MOVES 10000
char move_records[MAX_MOVES][50];  // 存储移动步骤
int move_count = 0;                // 记录移动总次数

// 汉诺塔递归函数
void hanoi(int n, char from_peg, char to_peg, char aux_peg) {
    if (n == 1) {
        snprintf(move_records[move_count], sizeof(move_records[move_count]), "%d: %c --> %c", n, from_peg, to_peg);
        move_count++;
        return;
    }
    hanoi(n - 1, from_peg, aux_peg, to_peg);
    snprintf(move_records[move_count], sizeof(move_records[move_count]), "%d: %c --> %c", n, from_peg, to_peg);
    move_count++;
    hanoi(n - 1, aux_peg, to_peg, from_peg);
}

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        move_count = 0;  // 每次输入新n时重置计数和记录
        hanoi(n, 'A', 'C', 'B');
        
        // 输出移动步骤
        for (int i = 0; i < move_count; i++) {
            printf("%s\n", move_records[i]);
        }
        printf("一共移动了%d次.\n", move_count);
    }
    return 0;
}

 

结果:

 

 

task6

 

代码:

#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) {
    if (m == 0 || m == n) {
        return 1;
    }
    if (m > n) {
        return 0;
    }
    int result = 1;
    for (int i = 0; i < m; i++) {
        result = result * (n - i) / (i + 1);
    }
    return result;
}
#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) {
    if (m == 0 || m == n) {
        return 1;
    }
    if (m > n) {
        return 0;
    }
    return func(n - 1, m) + func(n - 1, m - 1);
}

 

task7

代码:

#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_val = a;
    // 找出三个数中的最小值
    if (b < min_val) {
        min_val = b;
    }
    if (c < min_val) {
        min_val = c;
    }
    // 从最小值开始向下穷举
    for (int i = min_val; i >= 1; i--) {
        if (a % i == 0 && b % i == 0 && c % i == 0) {
            return i;
        }
    }
    return 1; // 理论上不会执行到这,除非输入全为0(但题目未明确处理,这里作为保底)
}

 

posted @ 2025-04-10 02:06  靓liang仔  阅读(13)  评论(0)    收藏  举报