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

文章目录

C语言五天速成 Day2:20道经典算法

题21:进制转换(十进制转二进制)

题目描述

输入一个非负整数n(0≤n≤1000),将其转换为二进制数并输出。要求手动实现转换逻辑,不使用库函数,处理n=0的特殊情况。

C语言实现

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

void decimalToBinary(int n) {
    if (n == 0) {
        printf("0"); // 特殊情况:0的二进制为0
        return;
    }
    int stack[32], top = -1; // 用栈存储二进制位(逆序输出)
    while (n > 0) {
        stack[++top] = n % 2;
        n = n / 2;
    }
    // 出栈输出(正序)
    while (top >= 0) {
        printf("%d", stack[top--]);
    }
}

int main() {
    int n;
    printf("请输入非负整数n:");
    scanf("%d", &n);
    if (n < 0 || n > 1000) {
        printf("输入无效,n需在0~1000之间\n");
        return 1;
    }
    printf("对应的二进制数:");
    decimalToBinary(n);
    printf("\n");
    return 0;
}

题22:进制转换(二进制转十进制)

题目描述

输入一个二进制字符串(长度≤10,仅含0和1),将其转换为十进制整数并输出。注意处理前导零的情况(如"00101"转换为5)。

C语言实现

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

int binaryToDecimal(char binary[]) {
    int len = strlen(binary);
    int decimal = 0;
    for (int i = 0; i < len; i++) {
        // 从左到右,每一位乘以2的对应次方
        decimal += (binary[i] - '0') * pow(2, len - 1 - i);
    }
    return decimal;
}

int main() {
    char binary[11];
    printf("请输入二进制字符串(仅含0和1):");
    scanf("%s", binary);
    // 验证输入是否为合法二进制
    for (int i = 0; i < strlen(binary); i++) {
        if (binary[i] != '0' && binary[i] != '1') {
            printf("输入无效,需为二进制字符串\n");
            return 1;
        }
    }
    int decimal = binaryToDecimal(binary);
    printf("对应的十进制数:%d\n", decimal);
    return 0;
}

题23:递归求最大公约数

题目描述

输入两个正整数a、b(1≤a,b≤10⁶),使用递归算法实现辗转相除法,计算它们的最大公约数(GCD)并输出。

C语言实现

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

// 递归版辗转相除法求GCD
long long gcdRecursive(long long a, long long b) {
    if (b == 0) {
        return a; // 递归终止条件
    }
    return gcdRecursive(b, a % 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", gcdRecursive(a, b));
    return 0;
}

题24:非递归求阶乘

题目描述

输入一个正整数n(1≤n≤20),使用循环(非递归)算法计算n的阶乘,使用long long类型存储结果,避免数据溢出。

C语言实现

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

long long factorialNonRecursive(int n) {
    long long result = 1;
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

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

题25:统计一个数的因子个数

题目描述

输入一个正整数n(1≤n≤10⁵),统计该数的所有正因子的个数(包括1和自身),优化算法减少循环次数。

C语言实现

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

int countFactors(int n) {
    if (n == 1) {
        return 1; // 1的因子只有自身
    }
    int count = 0;
    // 遍历到sqrt(n),成对统计因子
    for (int i = 1; i <= sqrt(n); i++) {
        if (n % i == 0) {
            if (i == n / i) {
                count++; // 因子相等,只算一个
            } else {
                count += 2; // 因子不相等,算两个
            }
        }
    }
    return count;
}

int main() {
    int n;
    printf("请输入正整数n:");
    scanf("%d", &n);
    if (n < 1 || n > 1e5) {
        printf("输入无效,n需在1~100000之间\n");
        return 1;
    }
    int num = countFactors(n);
    printf("%d的正因子个数:%d\n", n, num);
    return 0;
}

题26:字符串拼接(不使用strcat)

题目描述

输入两个字符串s1和s2(长度均≤50),手动实现字符串拼接功能(将s2拼接到s1末尾),不使用库函数strcat,输出拼接后的字符串。

C语言实现

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

void myStrcat(char s1[], char s2[]) {
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    // 将s2的字符逐个复制到s1末尾
    for (int i = 0; i <= len2; i++) { // 包含'\0'
        s1[len1 + i] = s2[i];
    }
}

int main() {
    char s1[101], s2[51]; // s1预留足够空间
    printf("请输入第一个字符串:");
    scanf("%s", s1);
    printf("请输入第二个字符串:");
    scanf("%s", s2);
    if (strlen(s1) + strlen(s2) > 100) {
        printf("字符串过长,拼接后会溢出\n");
        return 1;
    }
    myStrcat(s1, s2);
    printf("拼接后的字符串:%s\n", s1);
    return 0;
}

题27:选择排序(升序)

题目描述

输入一个长度为n(1≤n≤100)的整数数组,使用选择排序算法将数组按升序排列后输出。选择排序逻辑:每次选最小元素放到已排序部分末尾。

C语言实现

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

void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i; // 记录最小元素下标
        // 寻找未排序部分的最小元素
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 交换最小元素与当前位置元素
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = 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]);
    }
    selectionSort(arr, n);
    printf("升序排列后的数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

题28:打印杨辉三角(前n行)

题目描述

输入一个正整数n(1≤n≤10),打印杨辉三角的前n行。杨辉三角特点:每行首尾元素为1,其余元素为上一行相邻两元素之和。

C语言实现

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

int main() {
    int n;
    printf("请输入杨辉三角行数n:");
    scanf("%d", &n);
    if (n < 1 || n > 10) {
        printf("输入无效,行数需在1~10之间\n");
        return 1;
    }
    int yanghui[10][10] = {0};
    // 初始化杨辉三角
    for (int i = 0; i < n; i++) {
        yanghui[i][0] = 1; // 每行首元素为1
        yanghui[i][i] = 1; // 每行尾元素为1
        // 计算中间元素
        for (int j = 1; j < i; j++) {
            yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
        }
    }
    // 打印杨辉三角
    for (int i = 0; i < n; i++) {
        // 打印空格,使三角居中
        for (int j = 0; j < n - i - 1; j++) {
            printf(" ");
        }
        for (int j = 0; j <= i; j++) {
            printf("%d ", yanghui[i][j]);
        }
        printf("\n");
    }
    return 0;
}

题29:判断一个数是否为水仙花数

题目描述

输入一个三位数n(100≤n≤999),判断该数是否为水仙花数。水仙花数定义:一个三位数,其各位数字的立方和等于该数本身(如153=1³+5³+3³)。

C语言实现

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

int isNarcissisticNumber(int n) {
    int hundreds = n / 100; // 百位
    int tens = (n / 10) % 10; // 十位
    int units = n % 10; // 个位
    int sum = hundreds*hundreds*hundreds + tens*tens*tens + units*units*units;
    return sum == n;
}

int main() {
    int n;
    printf("请输入一个三位数:");
    scanf("%d", &n);
    if (n < 100 || n > 999) {
        printf("输入无效,需为三位数\n");
        return 1;
    }
    if (isNarcissisticNumber(n)) {
        printf("%d是水仙花数\n", n);
    } else {
        printf("%d不是水仙花数\n", n);
    }
    return 0;
}

题30:数组元素平移(右移k位)

题目描述

输入一个长度为n(1≤n≤100)的整数数组和一个整数k(1≤k≤n),将数组元素向右平移k位(循环右移),输出平移后的数组。例如:数组[1,2,3,4,5]右移2位后为[4,5,1,2,3]。

C语言实现

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

// 反转数组指定区间[left, right]
void reverse(int arr[], int left, int right) {
    while (left < right) {
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }
}

// 循环右移k位
void rightShift(int arr[], int n, int k) {
    k = k % n; // 处理k>n的情况
    reverse(arr, 0, n - 1); // 反转整个数组
    reverse(arr, 0, k - 1); // 反转前k位
    reverse(arr, k, n - 1); // 反转剩余部分
}

int main() {
    int n, k;
    printf("请输入数组长度和右移位数:");
    scanf("%d %d", &n, &k);
    if (n < 1 || n > 100 || k < 1) {
        printf("输入无效,长度需1~100,移位数≥1\n");
        return 1;
    }
    int arr[100];
    printf("请输入数组元素:");
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    rightShift(arr, n, k);
    printf("右移%d位后的数组:", k);
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

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

题目描述

输入一个字符串(长度≤100,含字母、数字、空格、标点),统计字符串中0-9每个数字出现的次数,忽略非数字字符,按数字顺序输出结果。

C语言实现

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

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

    for (int i = 0; i < strlen(str); i++) {
        if (isdigit(str[i])) { // 判断是否为数字
            count[str[i] - '0']++;
        }
    }

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

题32:递归实现字符串反转

题目描述

输入一个字符串(长度≤100,不含空格),使用递归算法实现字符串反转,输出反转后的字符串。

C语言实现

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

void reverseStringRecursive(char str[], int left, int right) {
    if (left >= right) {
        return; // 递归终止条件
    }
    // 交换左右字符
    char temp = str[left];
    str[left] = str[right];
    str[right] = temp;
    // 递归处理剩余部分
    reverseStringRecursive(str, left + 1, right - 1);
}

int main() {
    char str[101];
    printf("请输入字符串(不含空格):");
    scanf("%s", str);
    int len = strlen(str);
    reverseStringRecursive(str, 0, len - 1);
    printf("反转后的字符串:%s\n", str);
    return 0;
}

题33:求两个数组的交集(元素可重复)

题目描述

输入两个整数数组arr1和arr2(长度均≤50),求两个数组的交集(元素可重复,顺序与arr1一致),输出交集数组。例如:arr1=[1,2,2,1],arr2=[2,2],交集为[2,2]。

C语言实现

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

#define MAX_LEN 50

// 标记元素是否已被使用
void markUsed(int arr[], int len, int target, int used[]) {
    for (int i = 0; i < len; i++) {
        if (arr[i] == target && used[i] == 0) {
            used[i] = 1;
            break;
        }
    }
}

// 求交集
int getIntersection(int arr1[], int len1, int arr2[], int len2, int intersection[]) {
    int used[MAX_LEN] = {0}; // 标记arr2中元素是否已使用
    int idx = 0;
    for (int i = 0; i < len1; i++) {
        for (int j = 0; j < len2; j++) {
            if (arr1[i] == arr2[j] && used[j] == 0) {
                intersection[idx++] = arr1[i];
                markUsed(arr2, len2, arr1[i], used);
                break;
            }
        }
    }
    return idx; // 交集数组长度
}

int main() {
    int len1, len2, intersection[MAX_LEN];
    int arr1[MAX_LEN], arr2[MAX_LEN];
    printf("请输入arr1长度和元素:");
    scanf("%d", &len1);
    for (int i = 0; i < len1; i++) {
        scanf("%d", &arr1[i]);
    }
    printf("请输入arr2长度和元素:");
    scanf("%d", &len2);
    for (int i = 0; i < len2; i++) {
        scanf("%d", &arr2[i]);
    }
    int interLen = getIntersection(arr1, len1, arr2, len2, intersection);
    printf("两个数组的交集:");
    for (int i = 0; i < interLen; i++) {
        printf("%d ", intersection[i]);
    }
    printf("\n");
    return 0;
}

题34:打印倒直角三角形(星号)

题目描述

输入一个正整数n(1≤n≤10),打印一个直角边长度为n的倒直角三角形(直角在左上角),由星号组成。例如n=3时,图案如下:


**

C语言实现

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

int main() {
    int n;
    printf("请输入倒直角三角形直角边长度n:");
    scanf("%d", &n);
    if (n < 1 || n > 10) {
        printf("输入无效,长度需在1~10之间\n");
        return 1;
    }
    // 行数从n递减到1,每行星号数等于行数
    for (int i = n; i >= 1; i--) {
        for (int j = 1; j <= i; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

题35:计算一个数的二进制中1的个数

题目描述

输入一个非负整数n(0≤n≤1000),计算该数的二进制表示中1的个数并输出。使用位运算优化算法。

C语言实现

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

int countOneInBinary(int n) {
    int count = 0;
    while (n > 0) {
        n &= n - 1; // 清除最低位的1
        count++;
    }
    return count;
}

int main() {
    int n;
    printf("请输入非负整数n:");
    scanf("%d", &n);
    if (n < 0 || n > 1000) {
        printf("输入无效,n需在0~1000之间\n");
        return 1;
    }
    int num = countOneInBinary(n);
    printf("%d的二进制中1的个数:%d\n", n, num);
    return 0;
}

题36:字符串比较(不使用strcmp)

题目描述

输入两个字符串s1和s2(长度均≤50),手动实现字符串比较功能(不使用strcmp),按ASCII码值比较:s1>s2返回1,s1=s2返回0,s1<s2返回-1,输出结果。

C语言实现

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

int myStrcmp(char s1[], char s2[]) {
    int i = 0;
    // 逐字符比较,直到遇到'\0'或不同字符
    while (s1[i] != '\0' && s2[i] != '\0' && s1[i] == s2[i]) {
        i++;
    }
    // 返回ASCII码差值
    if (s1[i] > s2[i]) {
        return 1;
    } else if (s1[i] < s2[i]) {
        return -1;
    } else {
        return 0;
    }
}

int main() {
    char s1[51], s2[51];
    printf("请输入第一个字符串:");
    scanf("%s", s1);
    printf("请输入第二个字符串:");
    scanf("%s", s2);
    int res = myStrcmp(s1, s2);
    if (res == 1) {
        printf("s1 > s2\n");
    } else if (res == 0) {
        printf("s1 == s2\n");
    } else {
        printf("s1 < s2\n");
    }
    return 0;
}

题37:求数组的前缀和数组

题目描述

输入一个长度为n(1≤n≤100)的整数数组,计算其前缀和数组并输出。前缀和数组定义:prefix[i] = arr[0] + arr[1] + ... + arr[i]。

C语言实现

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

void getPrefixSum(int arr[], int n, int prefix[]) {
    prefix[0] = arr[0];
    for (int i = 1; i < n; i++) {
        prefix[i] = prefix[i-1] + arr[i];
    }
}

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

题38:递归实现斐波那契数列(带记忆化)

题目描述

输入一个正整数n(1≤n≤100),使用递归算法实现斐波那契数列,加入记忆化优化(避免重复计算),输出第n项。

C语言实现

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

long long memo[101] = {0}; // 记忆化数组,存储已计算的项

long long fibMemo(int n) {
    if (n <= 2) {
        return 1;
    }
    if (memo[n] != 0) {
        return memo[n]; // 已计算,直接返回
    }
    memo[n] = fibMemo(n-1) + fibMemo(n-2); // 计算并存储
    return memo[n];
}

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

题39:打印正六边形(星号)

题目描述

输入一个正整数n(2≤n≤5),打印一个边长为n的正六边形,由星号组成。例如n=2时,图案如下:

**




**

C语言实现

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

int main() {
    int n;
    printf("请输入正六边形边长n:");
    scanf("%d", &n);
    if (n < 2 || n > 5) {
        printf("输入无效,边长需在2~5之间\n");
        return 1;
    }
    int half = n - 1;
    // 上半部分(包括中间行)
    for (int i = 0; i < n; i++) {
        // 打印空格
        for (int j = 0; j < half - i; j++) {
            printf(" ");
        }
        // 打印星号
        for (int j = 0; j < n + 2 * i; j++) {
            printf("*");
        }
        printf("\n");
    }
    // 下半部分
    for (int i = n - 2; i >= 0; i--) {
        // 打印空格
        for (int j = 0; j < half - i; j++) {
            printf(" ");
        }
        // 打印星号
        for (int j = 0; j < n + 2 * i; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

题40:删除字符串中指定字符

题目描述

输入一个字符串(长度≤100)和一个指定字符c,删除字符串中所有的c字符,输出删除后的字符串。要求原地修改,不使用额外字符串空间。

C语言实现

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

void deleteChar(char str[], char c) {
    int idx = 0; // 记录有效字符下标
    for (int i = 0; i < strlen(str); i++) {
        if (str[i] != c) {
            str[idx++] = str[i];
        }
    }
    str[idx] = '\0'; // 加上字符串结束符
}

int main() {
    char str[101], c;
    printf("请输入字符串:");
    scanf("%s", str);
    printf("请输入要删除的字符:");
    scanf(" %c", &c); // 空格吸收换行
    deleteChar(str, c);
    printf("删除后的字符串:%s\n", str);
    return 0;
}
相关推荐
zhangkaixuan4562 小时前
Paimon Split 机制深度解析
java·算法·数据湖·lsm-tree·paimon
Yupureki2 小时前
《算法竞赛从入门到国奖》算法基础:搜索-BFS初识
c语言·数据结构·c++·算法·visual studio·宽度优先
Swift社区2 小时前
LeetCode 386 字典序排数:数字的字典序排序问题解析
算法·leetcode·职场和发展
嵌入式×边缘AI:打怪升级日志2 小时前
Libmodbus 源码总体分析:框架、数据结构与核心函数详解
开发语言·数据结构·php
Remember_9932 小时前
Spring 中 REST API 调用工具对比:RestTemplate vs OpenFeign
java·网络·后端·算法·spring·php
源代码•宸2 小时前
分布式理论基础——Raft算法
经验分享·分布式·后端·算法·golang·集群·raft
YiWait2 小时前
机器学习导论习题解答
人工智能·python·算法
流㶡2 小时前
scikit-learn之KNN算法实战鸢尾花分类
python·算法·scikit-learn·knn
啊阿狸不会拉杆2 小时前
《数字信号处理》第8章:有限长单位冲激响应(FIR)数字滤波器设计方法
算法·matlab·深度优先·信号处理·数字信号处理·dsp