经典问题合集
1. 累加和(连续整数、分数、加减交替)
1.1 连续整数
计算1+2+....100。
#include <stdio.h> int main() { int i,sum=0; for(i=1;i<=100;i++) { sum=sum+i; } printf("%d",sum); return 0; }
1.2 分数
输入正整数 n,计算以下数列的前 n 项之和:
2/1,3/2,5/3,8/5,13/8,21/13 ...
1) 分子、分母均为斐波那契数列,循环求和后滑动赋值
2) 可将所有数据类型都设为 float 或者 double 类型,避免整型带来的计算出错
3) 注意输入的数据类型为 float 或者 double 类型
#include <stdio.h> int main() { float up1=2,down1=1,up2=3,down2=2,up3,down3, n,i,sum=up1/down1+up2/down2; scanf("%f",&n); if(n==1) { sum=up1/down1; } else if(n==2) { sum=up1/down1+up2/down2; } else { for(i=3;i<=n;i++) { up3=up1+up2; down3=down1+down2; sum=sum+up3/down3; up1=up2; up2=up3; down1=down2; down2=down3; } } printf("%.2f",sum); return 0; }
1.3 加减交替
计算1 + 1/2 - 1/3 + 1/4 - 1/5 + 1/6 - ... + 1/n。
1) 可将所有数据类型都设为 float 或者 double 类型,避免整型带来的计算出错
2) 注意输入的数据类型为 float 或者 double 类型
#include <stdio.h> int main() { float sum=1,sign=1,i,n; scanf("%f",&n); for(i=2;i<=n;i++) { sum=sum+sign*(1/i); sign=-1*sign; } printf("%.3f",sum); return 0; }
2. 闰年
输入一个年份,判断是不是闰年。
四年一闰,百年不闰,四百年又闰
是闰年的两种情况:
1)不是百年,能被4整除--> (year%4 == 0) && (year%100 != 0)
2)是百年,能被400整除--> (year%400 == 0)
#include <stdio.h> int main() { int year; scanf("%d",&year); if(((year%4==0)&&(year%100!=0))||(year%400==0)) { printf("闰年"); } else { printf("平年"); } return 0; }
3. 排序(整数、字符、字符串)
3.1 整数
任意输入10个数,从小到大进行排序并输出。
输入:
10个数存为一个数组(包括负数)
输出(Output):
从小到大排序的10个数(空格相隔)
冒泡排序法:
1,2,3,4,5
n=5,
每一趟固定最大的数,需要4趟
每一趟无需比较已固定的数,第一趟需要比较4次
外层循环控制趟数,内层循环控制元素比较次数
//冒泡排序法 for(i=0;i<n-1;i++) { for(j=0;j<n-1-i;j++) { ... } } //选择排序法 for(i=0;i<n-1;i++) { for(j=i+1;j<n;j++) { ... } }
#include <stdio.h> int main() { int a[10],i,j,t,n=10; //循环输入 for(i=0;i<10;i++) { scanf("%d",&a[i]); } //冒泡排序 for(i=0;i<n-1;i++) { for(j=0;j<n-1-i;j++) { if(a[j]>a[j+1]) { t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } } //循环输出 for(i=0;i<10;i++) { printf("%d ",a[i]); } return 0; }
3.2 字符
将一个字符串中的元音字母(a、e、i、o、u)复制到另一个字符串,然后按照ASCII码从小到大的顺序输出。
输入(Input):
一行字符串
输出(Output):
输入字符串中的元音字母(按照ASCII码从小到大的顺序)
1) 判断是否元音字母,若是则赋值
2) 对字母冒泡排序
#include <stdio.h> #include <string.h> int main() { char str1[100],str2[100],i,j=0,t; gets(str1); //判断是否元音字母,若是则赋值 for(i=0;i<strlen(str1);i++) { if(str1[i]=='a'||str1[i]=='e'||str1[i]=='i'||str1[i]=='o'||str1[i]=='u'|| str1[i]=='A'||str1[i]=='E'||str1[i]=='I'||str1[i]=='O'||str1[i]=='U') { str2[j]=str1[i]; j++; } } str2[j]='\0'; //对字母冒泡排序 for(j=0;j<strlen(str2)-1;j++) { for(i=0;i<strlen(str2)-1-j;i++) { if(str2[i]>str2[i+1]) { t=str2[i]; str2[i]=str2[i+1]; str2[i+1]=t; } } } puts(str2); return 0; }
4. 素数
输入一个正整数,判断是不是素数。
1) 在 1~n 中,除了1和它自身n,不能其他数整除;即如能被整除,就不是素数
2) 用 sqrt(n) 代替 n(可等于 sqrt(n) ),等效,可避免运行超时
3) 注意 1 不是素数
//法一:定义法 #include <stdio.h> int main() { int n,i; scanf("%d",&n); if(n==1) { printf("不是素数"); } else { for(i=2;i<n;i++) { if(n%i==0) { printf("不是素数"); break; } } if(i==n) { printf("素数"); } } return 0; }
//法二:等效法 #include <stdio.h> #include <math.h> int main() { int n,i; scanf("%d",&n); if(n==1) { printf("不是素数"); } else { for(i=2;i<=sqrt(n);i++)//可等于sqrt(n) { if(n%i==0) { printf("不是素数"); break; } } if(i==int(sqrt(n))+1)//sqrt(n)可能不是整数,需用int()处理 { printf("素数"); } } return 0; }
5. 数字拆分
5.1 数字拆分求和
输入一个正整数,拆分各个位数的数字,直接求和。
123 / 10 = 12...3
12 / 10 = 1...2
1 / 10 = 0...1
0 / 10 = 0...0
1) 取余循环终止条件:
while (! ( ( n/10 == 0) && ( n%10 == 0))),其中用 ! 表示取补集
2) 特别地,仅当 (n%10 == 0) 不是充要条件
#include <stdio.h> int main() { int n,sum=0; scanf("%d",&n); while(!((n/10==0)&&(n%10==0))) { sum=sum+n%10; n=n/10; } printf("%d",sum); return 0; }
5.2 水仙花数
水仙花数是指一个3位数,每一位数字的3次幂的和正好等于这个数本身。
比如:153 = 1^3 + 5^3 + 3^3。
要求打印出所有三位数的水仙花数。
153 / 10 = 15...3 --> 153 / 10 = 15...3
15 / 10 = 1...5 --> 153 / 10 / 10 = 1...5
1 / 10 = 0...1 --> 153 / 10 / 10 / 10 = 0...1
1) pow() 函数只对 double 类型求幂
2) 符号%只对 int 类型取余
#include <stdio.h> #include <math.h> int main() { int i,sum=0; for(i=100;i<=999;i++) { sum=pow(double(int(i)%10),3)+ pow(double(int(i/10)%10),3)+ pow(double(int(i/10/10)%10),3); //可省略int if(sum==i) { printf("%d\n",sum); } } return 0; }
6. 字符串操作(拷贝、排序、连接、插入、删除、大小写转换、分类统计、逆序)
6.1 回文字符
所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"level"。
level:
str[0] --> str[4]
str[1] --> str[3]
str[2] --> str[2]
1) 只要有一对不同,就不是回文
2)若能循环到中间位置,就是回文
#include <stdio.h> #include <string.h> int main() { char str[10]; int i,n; gets(str); n=strlen(str); for(i=0;i<n/2;i++) { if(str[i]!=str[n-1-i]) { printf("N"); break; } } if(i==n/2) { printf("Y"); } return 0; }
6.2 连接
连接两个字符串(长度不超过20);不能使用puts,strcat等函数。
尽量将循环分开书写,避免报错。
#include <stdio.h> int main() { char str1[50],str2[25]; int i,j; scanf("%s",str1); scanf("%s",str2); //得到字符串1原始长度i for(i=0;i<=50;i++) { if(str1[i]=='\0') { break; } } //将字符串2逐个赋值给字符串1 for(j=0;j<=25;j++) { str1[i]=str2[j]; i++; } str1[i]='\0'; printf("%s",str1); return 0; }
8. 图形输出(数字沙漏图形、三角形、菱形)
8.1 K型图
要求根据输入的最多行的 * 数,打印由 * 形成的K字点阵。
例如:输入4,则打印如下的K型图案。
****
***
**
*
**
***
****
行1:4个* --> 和为定值,i<=n,((n+1)-i) 个*
行2:3个* --> 和为定值,i<=n,((n+1)-i) 个*
行3:2个* --> 和为定值,i<=n,((n+1)-i) 个*
行4:1个* --> 和为定值,i<=n,((n+1)-i) 个*
行5:2个* --> 差为定值,i>n,(i-(n-1)) 个*
行6:3个* --> 差为定值,i>n,(i-(n-1)) 个*
行7:4个* --> 差为定值,i>n,(i-(n-1)) 个*
1) 从和或差为定值出发,寻找规律的函数表达式;超过 n 行后规律反向
2) 外层循环控制行数,内层循环控制每行打出的 * 号数,内外层间输出换行
3) 终止条件不定,可用 for ( ; A?B:C ; ) 表示;若条件A成立则执行B,否则执行C
#include <stdio.h> int main() { int i,j,n; scanf("%d",&n); for(i=1;i<=2*n-1;i++)//控制行数 { for(j=1;i<=n?j<=(n+1)-i:j<=i-(n-1);j++)//控制每行打出的*号数 { printf("*"); } printf("\n"); } return 0; }
8.2 数字沙漏图形
对于输入的整数n(n>=0),打印2n+1行的由1~9的数字构造的数字沙漏。
例如:
输入:5
输出:
行6:左边0个空格,11个数 --> (n+1-i) 个空格,(2*i-1) 个数
行5:左边1个空格,9个数 --> (n+1-i) 个空格,(2*i-1) 个数
行4:左边2个空格,7个数 --> (n+1-i) 个空格,(2*i-1) 个数
行3:左边3个空格,5个数 --> (n+1-i) 个空格,(2*i-1) 个数
行2:左边4个空格,3个数 --> (n+1-i) 个空格,(2*i-1) 个数
行1:左边5个空格,1个数 --> (n+1-i) 个空格,(2*i-1) 个数
行2:左边4个空格,3个数 --> (n+1-i) 个空格,(2*i-1) 个数
行3:左边3个空格,5个数 --> (n+1-i) 个空格,(2*i-1) 个数
行4:左边2个空格,7个数 --> (n+1-i) 个空格,(2*i-1) 个数
行5:左边1个空格,9个数 --> (n+1-i) 个空格,(2*i-1) 个数
行6:左边0个空格,11个数 --> (n+1-i) 个空格,(2*i-1) 个数
1) 中间行编号1,往后顺序,往前逆序;使得每行递增打出
2) 外层循环控制行数,内层循环控制每行打出的数,内外层间输出换行
3) 在内层循环中数字自加,无需多加一层循环
#include <stdio.h> int main() { int n,i,j,k=1; scanf("%d",&n); for(i=n+1;i>1;i--)//前半段行号逆序 { for(j=1;j<=n+1-i;j++) { printf(" "); } for(j=1;j<=2*i-1;j++)//行号和每行数规律 { if(k==10) { k=1; } printf("%d",k); k++; } printf("\n"); } for(i=1;i<=n+1;i++)//后半段行号顺序 { for(j=1;j<=n+1-i;j++) { printf(" "); } for(j=1;j<=2*i-1;j++)//行号和每行数规律 { if(k==10) { k=1; } printf("%d",k); k++; } printf("\n"); } return 0; }
8.3 菱形
输入:5
输出:
行1:左4空格,1字母 --> 左 (n-i) 空格,(2*i-1) 字母
行2:左3空格,3字母 --> 左 (n-i) 空格,(2*i-1) 字母
行3:左2空格,5字母 --> 左 (n-i) 空格,(2*i-1) 字母
行4:左1空格,7字母 --> 左 (n-i) 空格,(2*i-1) 字母
行5:左0空格,9字母 --> 左 (n-i) 空格,(2*i-1) 字母
行4:左1空格,7字母 --> 左 (n-i) 空格,(2*i-1) 字母
行3:左2空格,5字母 --> 左 (n-i) 空格,(2*i-1) 字母
行2:左3空格,3字母 --> 左 (n-i) 空格,(2*i-1) 字母
行1:左4空格,1字母 --> 左 (n-i) 空格,(2*i-1) 字母
#include <stdio.h> int main() { int n,i,j; char k='A'; scanf("%d",&n); for(i=1;i<=n;i++) { for(j=1;j<=n-i;j++) { printf(" "); } for(j=1;j<=(2*i-1);j++) { printf("%c",k); } printf("\n"); k++; } for(i=n-1;i>=1;i--) { for(j=1;j<=n-i;j++) { printf(" "); } for(j=1;j<=(2*i-1);j++) { printf("%c",k); } printf("\n"); k++; } }
9. 进制转换、数字和字符串相互转换
9.1 进制转换
输入一个十进制的数,转换为相应的二进制数;
二进制要求为八位,所以输入的十进制数是有范围的。
输入:
2
输出:
00000010
2/2 = 1...0
1/2 = 0...1
0/2 = 0...0
0/2 = 0...0
...
1) 十进制转二进制:除2取余,逆序排列
2) 循环结束条件为8位数赋值完毕,无需设取余结束条件
#include <stdio.h> int main() { int n,i,two[8]; scanf("%d",&n); for(i=7;i>=0;i--) { two[i]=n%2; n=n/2; } for(i=0;i<8;i++) { printf("%d",two[i]); } return 0; }
排序法视频🔗:https://www.bilibili.com/video/BV1dX4y1g7cZ/?spm_id_from=333.337.search-card.all.click&vd_source=efad7d657bca9605bbc1590a798ed819
-END
//冒泡排序法 for(i=0;i<n-1;i++) { for(j=0;j<n-1-i;j++) { ... } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架