C语言五天算法速成(可用于备考蓝桥杯)

C语言五天算法速成

Day1:20道c语言算法

题1:非递归斐波那契数列

题目描述

输入一个正整数n(1≤n≤100),输出斐波那契数列的第n项。数列定义:F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)(n≥3)。要求使用非递归实现,避免栈溢出。

C语言实现

c 复制代码
#include <stdio.h>

int fibonacci(int n) {
    if (n <= 2) {
        return 1;
    }
    int a = 1, b = 1, res = 0;
    for (int i = 3; i <= n; i++) {
        res = a + b;
        a = b;
        b = res;
    }
    return res;
}

int main() {
    int n;
    printf("请输入正整数n:");
    scanf("%d", &n);
    if (n < 1 || n > 100) {
        printf("输入无效,n需在1~100之间\n");
        return 1;
    }
    printf("斐波那契数列第%d项:%d\n", n, fibonacci(n));
    return 0;
}

题2:最大公约数与最小公倍数

题目描述

输入两个正整数a、b(1≤a,b≤10⁶),使用辗转相除法计算它们的最大公约数(GCD),并根据GCD求出最小公倍数(LCM)。公式:LCM(a,b) = a*b / GCD(a,b),注意避免整数溢出。

C语言实现

c 复制代码
#include <stdio.h>

// 辗转相除法求最大公约数
long long gcd(long long a, long long b) {
    while (b != 0) {
        long long temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

// 求最小公倍数
long long lcm(long long a, long long b) {
    return a / gcd(a, b) * b; // 先除后乘避免溢出
}

int main() {
    long long a, b;
    printf("请输入两个正整数:");
    scanf("%lld %lld", &a, &b);
    if (a < 1 || b < 1) {
        printf("输入无效,请输入正整数\n");
        return 1;
    }
    printf("最大公约数(GCD):%lld\n", gcd(a, b));
    printf("最小公倍数(LCM):%lld\n", lcm(a, b));
    return 0;
}

题3:判断素数(高效版)

题目描述

输入一个正整数n(2≤n≤10⁸),判断该数是否为素数。要求优化算法,减少循环次数,提高效率。

C语言实现

c 复制代码
#include <stdio.h>
#include <math.h>

int isPrime(int n) {
    if (n == 2) {
        return 1; // 2是素数
    }
    if (n % 2 == 0) {
        return 0; // 偶数(除2外)不是素数
    }
    // 只遍历奇数,范围到sqrt(n)
    for (int i = 3; i <= sqrt(n); i += 2) {
        if (n % i == 0) {
            return 0;
        }
    }
    return 1;
}

int main() {
    int n;
    printf("请输入正整数n:");
    scanf("%d", &n);
    if (n < 2) {
        printf("输入无效,n需≥2\n");
        return 1;
    }
    if (isPrime(n)) {
        printf("%d是素数\n", n);
    } else {
        printf("%d不是素数\n", n);
    }
    return 0;
}

题4:数组元素逆序输出

题目描述

输入一个长度为n(1≤n≤100)的整数数组,将数组元素逆序排列后输出,要求不使用额外数组空间(原地逆序)。

C语言实现

c 复制代码
#include <stdio.h>

void reverseArray(int arr[], int n) {
    // 首尾交换元素
    for (int i = 0; i < n / 2; i++) {
        int temp = arr[i];
        arr[i] = arr[n - 1 - i];
        arr[n - 1 - i] = temp;
    }
}

int main() {
    int n;
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n < 1 || n > 100) {
        printf("输入无效,长度需在1~100之间\n");
        return 1;
    }
    int arr[100];
    printf("请输入数组元素:");
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    reverseArray(arr, n);
    printf("逆序后的数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

题5:求数组中的最大值和最小值

题目描述

输入一个长度为n(1≤n≤1000)的整数数组,遍历一次数组同时求出最大值和最小值,输出结果。

C语言实现

c 复制代码
#include <stdio.h>

void findMaxMin(int arr[], int n, int *max, int *min) {
    *max = *min = arr[0];
    for (int i = 1; i < n; i++) {
        if (arr[i] > *max) {
            *max = arr[i];
        }
        if (arr[i] < *min) {
            *min = arr[i];
        }
    }
}

int main() {
    int n, max, min;
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n < 1 || n > 1000) {
        printf("输入无效,长度需在1~1000之间\n");
        return 1;
    }
    int arr[1000];
    printf("请输入数组元素:");
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    findMaxMin(arr, n, &max, &min);
    printf("数组最大值:%d\n", max);
    printf("数组最小值:%d\n", min);
    return 0;
}

题6:字符串反转(含空格)

题目描述

输入一个字符串(长度≤100,含字母、数字、空格),将字符串整体反转后输出,要求原地反转,不使用额外字符串空间。

C语言实现

c 复制代码
#include <stdio.h>
#include <string.h>

void reverseString(char str[]) {
    int len = strlen(str);
    for (int i = 0; i < len / 2; i++) {
        char temp = str[i];
        str[i] = str[len - 1 - i];
        str[len - 1 - i] = temp;
    }
}

int main() {
    char str[101];
    printf("请输入字符串:");
    getchar(); // 吸收scanf残留的换行符
    fgets(str, 101, stdin);
    // 去除fgets读取的换行符
    str[strcspn(str, "\n")] = '\0';
    reverseString(str);
    printf("反转后的字符串:%s\n", str);
    return 0;
}

题7:统计字符串中字母出现次数

题目描述

输入一个字符串(仅含大小写字母、空格),统计每个英文字母(不区分大小写)出现的次数,忽略空格,按字母顺序输出结果。

C语言实现

c 复制代码
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main() {
    char str[1001];
    int count[26] = {0}; // 存储a-z的出现次数
    printf("请输入字符串:");
    getchar();
    fgets(str, 1001, stdin);
    str[strcspn(str, "\n")] = '\0';

    for (int i = 0; i < strlen(str); i++) {
        if (isalpha(str[i])) { // 判断是否为字母
            char lower = tolower(str[i]); // 转为小写
            count[lower - 'a']++;
        }
    }

    printf("字母出现次数统计:\n");
    for (int i = 0; i < 26; i++) {
        if (count[i] > 0) {
            printf("%c/%c:%d次\n", 'a' + i, 'A' + i, count[i]);
        }
    }
    return 0;
}

题8:冒泡排序(升序)

题目描述

输入一个长度为n(1≤n≤100)的整数数组,使用冒泡排序算法将数组按升序排列后输出,优化算法(加入标志位,无交换时提前退出)。

C语言实现

c 复制代码
#include <stdio.h>

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int flag = 0; // 标志位,判断是否有交换
        for (int j = 0; j < n - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                // 交换元素
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                flag = 1;
            }
        }
        if (flag == 0) {
            break; // 无交换,数组已有序
        }
    }
}

int main() {
    int n;
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n < 1 || n > 100) {
        printf("输入无效,长度需在1~100之间\n");
        return 1;
    }
    int arr[100];
    printf("请输入数组元素:");
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    bubbleSort(arr, n);
    printf("升序排列后的数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

题9:插入排序(降序)

题目描述

输入一个长度为n(1≤n≤100)的整数数组,使用插入排序算法将数组按降序排列后输出。

C语言实现

c 复制代码
#include <stdio.h>

void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i - 1;
        // 寻找插入位置,降序排列
        while (j >= 0 && arr[j] < key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}

int main() {
    int n;
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n < 1 || n > 100) {
        printf("输入无效,长度需在1~100之间\n");
        return 1;
    }
    int arr[100];
    printf("请输入数组元素:");
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    insertionSort(arr, n);
    printf("降序排列后的数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

题10:求一个数的阶乘(递归版)

题目描述

输入一个正整数n(1≤n≤20),使用递归算法计算n的阶乘(n! = n×(n-1)×...×1),注意数据溢出问题,使用long long类型存储结果。

C语言实现

c 复制代码
#include <stdio.h>

long long factorial(int n) {
    if (n == 1) {
        return 1; // 递归终止条件
    }
    return n * factorial(n - 1); // 递归调用
}

int main() {
    int n;
    printf("请输入正整数n:");
    scanf("%d", &n);
    if (n < 1 || n > 20) {
        printf("输入无效,n需在1~20之间\n");
        return 1;
    }
    printf("%d的阶乘:%lld\n", n, factorial(n));
    return 0;
}

题11:判断回文字符串

题目描述

输入一个字符串(仅含字母、数字,不区分大小写),判断该字符串是否为回文字符串(正读和反读一致)。

C语言实现

c 复制代码
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int isPalindrome(char str[]) {
    int left = 0;
    int right = strlen(str) - 1;
    while (left < right) {
        // 转为小写比较
        char lc = tolower(str[left]);
        char rc = tolower(str[right]);
        if (lc != rc) {
            return 0;
        }
        left++;
        right--;
    }
    return 1;
}

int main() {
    char str[101];
    printf("请输入字符串:");
    scanf("%s", str);
    if (isPalindrome(str)) {
        printf("%s是回文字符串\n", str);
    } else {
        printf("%s不是回文字符串\n", str);
    }
    return 0;
}

题12:计算两个数的差(绝对值)

题目描述

输入两个整数a、b,计算并输出它们的差值的绝对值(|a - b|),要求不使用库函数abs(),自己实现绝对值逻辑。

C语言实现

c 复制代码
#include <stdio.h>

int myAbs(int x) {
    return x < 0 ? -x : x; // 三目运算符实现绝对值
}

int main() {
    int a, b;
    printf("请输入两个整数:");
    scanf("%d %d", &a, &b);
    int diff = myAbs(a - b);
    printf("两数差值的绝对值:%d\n", diff);
    return 0;
}

题13:数组元素求和与平均值

题目描述

输入一个长度为n(1≤n≤100)的浮点数数组,计算数组所有元素的和与平均值,平均值保留2位小数输出。

C语言实现

c 复制代码
#include <stdio.h>

int main() {
    int n;
    float sum = 0.0f, avg = 0.0f;
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n < 1 || n > 100) {
        printf("输入无效,长度需在1~100之间\n");
        return 1;
    }
    float arr[100];
    printf("请输入数组元素(浮点数):");
    for (int i = 0; i < n; i++) {
        scanf("%f", &arr[i]);
        sum += arr[i];
    }
    avg = sum / n;
    printf("数组元素总和:%.2f\n", sum);
    printf("数组元素平均值:%.2f\n", avg);
    return 0;
}

题14:打印九九乘法表(左上三角)

题目描述

使用循环打印左上三角形式的九九乘法表,格式规范,每个乘积占4个字符宽度。

C语言实现

c 复制代码
#include <stdio.h>

int main() {
    // 左上三角:i控制行数,j控制列数,j≤i
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= i; j++) {
            printf("%d×%d=%2d ", j, i, i*j);
        }
        printf("\n");
    }
    return 0;
}

题15:统计数组中偶数和奇数的个数

题目描述

输入一个长度为n(1≤n≤1000)的整数数组,统计数组中偶数和奇数的个数,分别输出结果。

C语言实现

c 复制代码
#include <stdio.h>

int main() {
    int n, even = 0, odd = 0;
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n < 1 || n > 1000) {
        printf("输入无效,长度需在1~1000之间\n");
        return 1;
    }
    int arr[1000];
    printf("请输入数组元素:");
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
        if (arr[i] % 2 == 0) {
            even++;
        } else {
            odd++;
        }
    }
    printf("数组中偶数的个数:%d\n", even);
    printf("数组中奇数的个数:%d\n", odd);
    return 0;
}

题16:字符串替换(指定字符)

题目描述

输入一个字符串、目标字符c1和替换字符c2,将字符串中所有的c1替换为c2,输出替换后的字符串。

C语言实现

c 复制代码
#include <stdio.h>
#include <string.h>

void replaceChar(char str[], char c1, char c2) {
    for (int i = 0; i < strlen(str); i++) {
        if (str[i] == c1) {
            str[i] = c2;
        }
    }
}

int main() {
    char str[101], c1, c2;
    printf("请输入字符串:");
    scanf("%s", str);
    printf("请输入目标字符c1和替换字符c2:");
    scanf(" %c %c", &c1, &c2); // 空格吸收换行
    replaceChar(str, c1, c2);
    printf("替换后的字符串:%s\n", str);
    return 0;
}

题17:递归求等差数列和

题目描述

已知等差数列的首项a1、公差d和项数n(1≤n≤100),使用递归算法计算该等差数列前n项的和。公式:S(n) = a1 + (a1+d) + ... + (a1+(n-1)d)。

C语言实现

c 复制代码
#include <stdio.h>

int arithmeticSum(int a1, int d, int n) {
    if (n == 1) {
        return a1; // 递归终止条件:第一项和为自身
    }
    // 第n项为a1+(n-1)d,递归求和
    return (a1 + (n - 1) * d) + arithmeticSum(a1, d, n - 1);
}

int main() {
    int a1, d, n;
    printf("请输入等差数列首项a1、公差d、项数n:");
    scanf("%d %d %d", &a1, &d, &n);
    if (n < 1 || n > 100) {
        printf("输入无效,项数n需在1~100之间\n");
        return 1;
    }
    int sum = arithmeticSum(a1, d, n);
    printf("等差数列前%d项和:%d\n", n, sum);
    return 0;
}

题18:判断一个数是否为完数

题目描述

输入一个正整数n(6≤n≤10000),判断该数是否为完数。完数定义:一个数等于它的所有真因子(不包括自身)之和,例如6=1+2+3。

C语言实现

c 复制代码
#include <stdio.h>
#include <math.h>

int isPerfectNumber(int n) {
    if (n < 6) {
        return 0;
    }
    int sum = 1; // 1是所有数的真因子
    // 遍历到sqrt(n),减少循环次数
    for (int i = 2; i <= sqrt(n); i++) {
        if (n % i == 0) {
            sum += i;
            if (i != n / i) { // 避免重复加因子(如4的因子2)
                sum += n / i;
            }
        }
    }
    return sum == n;
}

int main() {
    int n;
    printf("请输入正整数n:");
    scanf("%d", &n);
    if (n < 6 || n > 10000) {
        printf("输入无效,n需在6~10000之间\n");
        return 1;
    }
    if (isPerfectNumber(n)) {
        printf("%d是完数\n", n);
    } else {
        printf("%d不是完数\n", n);
    }
    return 0;
}

题19:数组去重(保留首次出现)

题目描述

输入一个长度为n(1≤n≤100)的整数数组,去除数组中的重复元素,保留元素首次出现的位置,输出去重后的数组及长度。

C语言实现

c 复制代码
#include <stdio.h>

// 判断元素是否已存在于新数组中
int isExist(int newArr[], int len, int num) {
    for (int i = 0; i < len; i++) {
        if (newArr[i] == num) {
            return 1;
        }
    }
    return 0;
}

int main() {
    int n, newLen = 0;
    int arr[100], newArr[100];
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n < 1 || n > 100) {
        printf("输入无效,长度需在1~100之间\n");
        return 1;
    }
    printf("请输入数组元素:");
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
        // 不存在则加入新数组
        if (!isExist(newArr, newLen, arr[i])) {
            newArr[newLen++] = arr[i];
        }
    }
    printf("去重后的数组:");
    for (int i = 0; i < newLen; i++) {
        printf("%d ", newArr[i]);
    }
    printf("\n去重后数组长度:%d\n", newLen);
    return 0;
}

题20:打印菱形图案(边长为n)

题目描述

输入一个正整数n(3≤n≤10),打印一个边长为n的菱形图案,由星号(*)组成,图案对称。

C语言实现

c 复制代码
#include <stdio.h>

int main() {
    int n;
    printf("请输入菱形边长n(3≤n≤10):");
    scanf("%d", &n);
    if (n < 3 || n > 10) {
        printf("输入无效,边长需在3~10之间\n");
        return 1;
    }
    // 上半部分(包括中间行)
    for (int i = 1; i <= n; i++) {
        // 打印空格
        for (int j = 1; j <= n - i; j++) {
            printf(" ");
        }
        // 打印星号
        for (int j = 1; j <= 2 * i - 1; j++) {
            printf("*");
        }
        printf("\n");
    }
    // 下半部分
    for (int i = n - 1; i >= 1; i--) {
        // 打印空格
        for (int j = 1; j <= n - i; j++) {
            printf(" ");
        }
        // 打印星号
        for (int j = 1; j <= 2 * i - 1; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}
相关推荐
无限进步_2 小时前
203. 移除链表元素 - 题解与详细分析
c语言·开发语言·数据结构·git·链表·github·visual studio
闻缺陷则喜何志丹2 小时前
【前缀树(字典树)】P12124 [蓝桥杯 2024 省 B 第二场] 前缀总分|普及+
c++·算法·蓝桥杯·字典树·前缀树·洛谷
油泼辣子多加2 小时前
【信创】华为昇腾NLP算法训练
人工智能·算法·机器学习·华为·自然语言处理
tudficdew2 小时前
C++中的策略模式实战
开发语言·c++·算法
naruto_lnq2 小时前
实时语音处理库
开发语言·c++·算法
独自破碎E2 小时前
【数组】分糖果问题
java·开发语言·算法
10岁的博客2 小时前
C语言造轮子大赛
java·c语言·数据结构
@Aurora.2 小时前
优选算法【专题七:分治】
数据结构·算法·排序算法
程序员敲代码吗2 小时前
C++与硬件交互编程
开发语言·c++·算法