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;
}