C语言五天速成(可用于蓝桥杯备考 难度中等偏下)

Day3:20道核心题型(C语言实现)

题41:求两个数组的并集(去重)

题目描述

输入两个整数数组arr1和arr2(长度均≤50),求两个数组的并集(去除重复元素,顺序无要求),输出并集数组及长度。

C语言实现

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

#define MAX_LEN 100

// 判断元素是否在数组中
int isInArray(int arr[], int len, int num) {
    for (int i = 0; i < len; i++) {
        if (arr[i] == num) {
            return 1;
        }
    }
    return 0;
}

// 求并集(去重)
int getUnion(int arr1[], int len1, int arr2[], int len2, int unionArr[]) {
    int idx = 0;
    // 加入arr1的元素(去重)
    for (int i = 0; i < len1; i++) {
        if (!isInArray(unionArr, idx, arr1[i])) {
            unionArr[idx++] = arr1[i];
        }
    }
    // 加入arr2中不在并集中的元素
    for (int i = 0; i < len2; i++) {
        if (!isInArray(unionArr, idx, arr2[i])) {
            unionArr[idx++] = arr2[i];
        }
    }
    return idx; // 并集长度
}

int main() {
    int len1, len2, unionArr[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 unionLen = getUnion(arr1, len1, arr2, len2, unionArr);
    printf("两个数组的并集(去重):");
    for (int i = 0; i < unionLen; i++) {
        printf("%d ", unionArr[i]);
    }
    printf("\n并集长度:%d\n", unionLen);
    return 0;
}

题42:进制转换(十进制转八进制)

题目描述

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

C语言实现

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

void decimalToOctal(int n) {
    if (n == 0) {
        printf("0");
        return;
    }
    int stack[32], top = -1; // 栈存储八进制位
    while (n > 0) {
        stack[++top] = n % 8;
        n = n / 8;
    }
    // 出栈输出
    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("对应的八进制数:");
    decimalToOctal(n);
    printf("\n");
    return 0;
}

题43:八进制转十进制

题目描述

输入一个八进制字符串(长度≤10,仅含0-7),将其转换为十进制整数并输出。处理前导零情况,验证输入合法性。

C语言实现

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

int octalToDecimal(char octal[]) {
    int len = strlen(octal);
    int decimal = 0;
    for (int i = 0; i < len; i++) {
        decimal += (octal[i] - '0') * pow(8, len - 1 - i);
    }
    return decimal;
}

int main() {
    char octal[11];
    printf("请输入八进制字符串(仅含0-7):");
    scanf("%s", octal);
    // 验证输入合法性
    for (int i = 0; i < strlen(octal); i++) {
        if (octal[i] < '0' || octal[i] > '7') {
            printf("输入无效,需为八进制字符串\n");
            return 1;
        }
    }
    int decimal = octalToDecimal(octal);
    printf("对应的十进制数:%d\n", decimal);
    return 0;
}

题44:希尔排序(升序)

题目描述

输入一个长度为n(1≤n≤100)的整数数组,使用希尔排序算法将数组按升序排列后输出。希尔排序逻辑:按增量分组,每组插入排序,逐步减小增量至1。

C语言实现

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

void shellSort(int arr[], int n) {
    // 增量逐步减半
    for (int gap = n / 2; gap > 0; gap /= 2) {
        // 分组插入排序
        for (int i = gap; i < n; i++) {
            int key = arr[i];
            int j = i - gap;
            while (j >= 0 && arr[j] > key) {
                arr[j + gap] = arr[j];
                j -= gap;
            }
            arr[j + gap] = 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]);
    }
    shellSort(arr, n);
    printf("升序排列后的数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

题45:求一个数的所有真因子

题目描述

输入一个正整数n(2≤n≤1000),输出该数的所有真因子(不包括自身,包括1),按从小到大的顺序排列。

C语言实现

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

void printProperFactors(int n) {
    printf("%d的真因子:", n);
    for (int i = 1; i <= n / 2; i++) {
        if (n % i == 0) {
            printf("%d ", i);
        }
    }
    printf("\n");
}

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

题46:字符串截取(不使用strncpy)

题目描述

输入一个字符串s、起始下标start和截取长度len,手动实现字符串截取功能(从start开始截取len个字符),不使用strncpy,输出截取后的字符串。处理边界情况(start超出范围、len超出剩余长度)。

C语言实现

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

void myStrncpy(char dest[], char src[], int start, int len) {
    int srcLen = strlen(src);
    int idx = 0;
    // 处理start超出范围
    if (start >= srcLen) {
        dest[0] = '\0';
        return;
    }
    // 截取len个字符,或剩余所有字符
    for (int i = start; i < srcLen && idx < len; i++) {
        dest[idx++] = src[i];
    }
    dest[idx] = '\0';
}

int main() {
    char s[101], sub[101];
    int start, len;
    printf("请输入字符串:");
    scanf("%s", s);
    printf("请输入起始下标和截取长度:");
    scanf("%d %d", &start, &len);
    if (start < 0 || len < 0) {
        printf("起始下标和长度需非负\n");
        return 1;
    }
    myStrncpy(sub, s, start, len);
    printf("截取后的字符串:%s\n", sub);
    return 0;
}

题47:递归实现阶乘求和

题目描述

输入一个正整数n(1≤n≤10),使用递归算法计算1! + 2! + ... + n! 的和,输出结果。

C语言实现

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

// 递归求n的阶乘
long long factorial(int n) {
    if (n == 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

// 递归求阶乘和
long long factorialSum(int n) {
    if (n == 1) {
        return 1;
    }
    return factorial(n) + factorialSum(n - 1);
}

int main() {
    int n;
    printf("请输入正整数n:");
    scanf("%d", &n);
    if (n < 1 || n > 10) {
        printf("输入无效,n需在1~10之间\n");
        return 1;
    }
    long long sum = factorialSum(n);
    printf("1!+2!+...+%d! = %lld\n", n, sum);
    return 0;
}

题48:打印等腰梯形(星号)

题目描述

输入一个正整数n(2≤n≤5),打印一个上底为n、下底为2n-1、高为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 bottom = 2 * n - 1; // 下底长度
    int height = n; // 高度(行数)
    // 逐行打印,每行星号数递增1,空格数递减1
    for (int i = 0; i < height; i++) {
        // 打印左侧空格,使梯形居中
        for (int j = 0; j < (bottom - (n + i)) / 2; j++) {
            printf(" ");
        }
        // 打印星号,当前行星号数 = 上底 + 行数i
        for (int j = 0; j < n + i; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

题49:统计字符串中大写字母出现次数

题目描述

输入一个字符串(长度≤100,含大小写字母、数字、空格、标点),统计字符串中大写英文字母(A-Z)的出现次数,忽略其他字符,输出结果。

C语言实现

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

int main() {
    char str[101];
    int count = 0;
    printf("请输入字符串:");
    getchar(); // 吸收换行符
    fgets(str, 101, stdin);
    str[strcspn(str, "\n")] = '\0';

    for (int i = 0; i < strlen(str); i++) {
        if (isupper(str[i])) { // 判断是否为大写字母
            count++;
        }
    }

    printf("字符串中大写字母出现次数:%d\n", count);
    return 0;
}

题50:数组元素左移k位

题目描述

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

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 leftShift(int arr[], int n, int k) {
    k = k % n; // 处理k>n的情况
    reverse(arr, 0, k - 1); // 反转前k位
    reverse(arr, k, n - 1); // 反转剩余部分
    reverse(arr, 0, 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]);
    }
    leftShift(arr, n, k);
    printf("左移%d位后的数组:", k);
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

题51:判断一个数是否为平方数

题目描述

输入一个非负整数n(0≤n≤10⁶),判断该数是否为完全平方数(存在整数x使得x²=n),优化算法减少循环次数。

C语言实现

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

int isPerfectSquare(int n) {
    if (n < 0) {
        return 0;
    }
    if (n == 0 || n == 1) {
        return 1;
    }
    int left = 1, right = n / 2;
    // 二分查找优化
    while (left <= right) {
        long long mid = (left + right) / 2; // 用long long避免溢出
        long long square = mid * mid;
        if (square == n) {
            return 1;
        } else if (square < n) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return 0;
}

int main() {
    int n;
    printf("请输入非负整数n:");
    scanf("%d", &n);
    if (n < 0 || n > 1e6) {
        printf("输入无效,n需在0~1000000之间\n");
        return 1;
    }
    if (isPerfectSquare(n)) {
        printf("%d是完全平方数\n", n);
    } else {
        printf("%d不是完全平方数\n", n);
    }
    return 0;
}

题52:字符串大小写转换

题目描述

输入一个字符串(长度≤100,含大小写字母、数字、空格),将字符串中的大写字母转为小写,小写字母转为大写,其他字符不变,输出转换后的字符串。手动实现转换逻辑,不使用toupper/tolower。

C语言实现

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

void swapCase(char str[]) {
    int len = strlen(str);
    for (int i = 0; i < len; i++) {
        // 大写转小写:ASCII码+32
        if (str[i] >= 'A' && str[i] <= 'Z') {
            str[i] += 32;
        }
        // 小写转大写:ASCII码-32
        else if (str[i] >= 'a' && str[i] <= 'z') {
            str[i] -= 32;
        }
        // 其他字符不变
    }
}

int main() {
    char str[101];
    printf("请输入字符串:");
    getchar();
    fgets(str, 101, stdin);
    str[strcspn(str, "\n")] = '\0';

    swapCase(str);
    printf("大小写转换后的字符串:%s\n", str);
    return 0;
}

题53:递归实现数组求和

题目描述

输入一个长度为n(1≤n≤100)的整数数组,使用递归算法计算数组所有元素的和,输出结果。

C语言实现

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

// 递归求数组和,index为当前处理的下标
int arraySum(int arr[], int index, int n) {
    if (index == n - 1) {
        return arr[index]; // 递归终止,最后一个元素
    }
    return arr[index] + arraySum(arr, index + 1, n);
}

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]);
    }
    int sum = arraySum(arr, 0, n);
    printf("数组所有元素的和:%d\n", sum);
    return 0;
}

题54:打印平行四边形(星号)

题目描述

输入一个正整数n(2≤n≤5),打印一个底和高均为n的平行四边形,由星号组成。例如n=3时,图案如下:




(注:每行前有n-1个空格,星号数为n)

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 spaceNum = n - 1; // 每行前的空格数
    for (int i = 0; i < n; i++) {
        // 打印空格
        for (int j = 0; j < spaceNum; j++) {
            printf(" ");
        }
        // 打印星号
        for (int j = 0; j < n; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

题55:计算两个数的最小公倍数(非递归版)

题目描述

输入两个正整数a、b(1≤a,b≤10⁶),使用非递归辗转相除法求最大公约数,再计算最小公倍数,避免整数溢出,输出结果。

C语言实现

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

// 非递归辗转相除法求GCD
long long gcd(long long a, long long b) {
    while (b != 0) {
        long long temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

// 求LCM,先除后乘避免溢出
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("最小公倍数(LCM):%lld\n", lcm(a, b));
    return 0;
}

题56:字符串去空格(首尾+中间)

题目描述

输入一个字符串(长度≤100),删除字符串中所有空格(包括首尾空格和中间空格),原地修改,输出处理后的字符串。

C语言实现

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

void removeSpace(char str[]) {
    int idx = 0;
    int len = strlen(str);
    for (int i = 0; i < len; i++) {
        if (str[i] != ' ') {
            str[idx++] = str[i];
        }
    }
    str[idx] = '\0'; // 加上结束符
}

int main() {
    char str[101];
    printf("请输入字符串:");
    getchar();
    fgets(str, 101, stdin);
    str[strcspn(str, "\n")] = '\0';

    removeSpace(str);
    printf("删除所有空格后的字符串:%s\n", str);
    return 0;
}

题57:求数组中第二大的数

题目描述

输入一个长度为n(2≤n≤100)的整数数组,数组元素互不相同,找出数组中第二大的数,输出结果。遍历一次数组完成查找。

C语言实现

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

int findSecondMax(int arr[], int n) {
    int max1, max2;
    // 初始化最大值和第二大值
    if (arr[0] > arr[1]) {
        max1 = arr[0];
        max2 = arr[1];
    } else {
        max1 = arr[1];
        max2 = arr[0];
    }
    // 遍历剩余元素
    for (int i = 2; i < n; i++) {
        if (arr[i] > max1) {
            max2 = max1;
            max1 = arr[i];
        } else if (arr[i] > max2) {
            max2 = arr[i];
        }
    }
    return max2;
}

int main() {
    int n;
    printf("请输入数组长度:");
    scanf("%d", &n);
    if (n < 2 || n > 100) {
        printf("输入无效,长度需在2~100之间\n");
        return 1;
    }
    int arr[100];
    printf("请输入数组元素(互不相同):");
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    int secondMax = findSecondMax(arr, n);
    printf("数组中第二大的数:%d\n", secondMax);
    return 0;
}

题58:递归实现二进制转十进制

题目描述

输入一个二进制字符串(长度≤10,仅含0和1),使用递归算法将其转换为十进制整数,输出结果。

C语言实现

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

// 递归转换,index为当前处理的下标
long long binaryToDecimalRecursive(char binary[], int index, int len) {
    if (index == len - 1) {
        return binary[index] - '0'; // 最后一位直接返回
    }
    // 当前位值 + 后续位值*2
    return (binary[index] - '0') * (1LL << (len - 1 - index)) + binaryToDecimalRecursive(binary, index + 1, len);
}

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

题59:打印空心菱形(星号)

题目描述

输入一个正整数n(3≤n≤10),打印一个边长为n的空心菱形,由星号组成,边框为*,内部为空格。例如n=3时,图案如下:




C语言实现

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

int main() {
    int n;
    printf("请输入空心菱形边长n:");
    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++) {
            if (j == 1 || j == 2 * i - 1 || i == n) {
                printf("*");
            } else {
                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++) {
            if (j == 1 || j == 2 * i - 1) {
                printf("*");
            } else {
                printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}

题60:删除数组中指定元素(所有出现)

题目描述

输入一个长度为n(1≤n≤100)的整数数组和一个指定整数x,删除数组中所有值等于x的元素,保留剩余元素的顺序,输出处理后的数组及长度。原地修改,不使用额外数组。

C语言实现

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

// 删除数组中所有x,返回新长度
int deleteElement(int arr[], int n, int x) {
    int idx = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] != x) {
            arr[idx++] = arr[i];
        }
    }
    return idx;
}

int main() {
    int n, x;
    printf("请输入数组长度和指定删除元素:");
    scanf("%d %d", &n, &x);
    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]);
    }
    int newLen = deleteElement(arr, n, x);
    printf("删除元素%d后的数组:", x);
    for (int i = 0; i < newLen; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n处理后数组长度:%d\n", newLen);
    return 0;
}
相关推荐
进击的小头2 小时前
设计模式组合应用:嵌入式通信协议栈
c语言·设计模式·策略模式
爱尔兰极光2 小时前
LeetCode--有序数组的平方
算法·leetcode·职场和发展
jay神2 小时前
森林火灾检测数据集
算法·机器学习·目标跟踪
闻缺陷则喜何志丹2 小时前
【栈 递归】P8650 [蓝桥杯 2017 省 A] 正则问题|普及+
c++·数学·蓝桥杯·递归·
80530单词突击赢2 小时前
STLVector底层原理与高效运用
数据结构·算法
haluhalu.2 小时前
LeetCode---基础算法刷题指南
数据结构·算法·leetcode
iAkuya2 小时前
(leetcode)力扣100 58组合总和(回溯)
算法·leetcode·职场和发展
80530单词突击赢2 小时前
C++关联容器深度解析:set/map全攻略
java·数据结构·算法
m0_561359672 小时前
代码热更新技术
开发语言·c++·算法