C语言经典编程题(上)
三个数从小到大排序/输出猴子吃桃问题百钱买百鸡渔夫打鱼晒网问题希尔排序算法冒泡排序算法直接插入排序算法快速排序算法选择排序算法归并排序算法二分查找算法,折半查找算法言分块查找算法,索引顺序查找算法求n的阶乘(n!)判断三角形的类型水仙花数,阿姆斯特朗数最大公约数和最小公倍数求自然底数e小写字母转换成大写字母求回文素数判断年份是否为闰年矩阵转置兔子生兔子问题狼追兔子问题谁家孩子跑得最慢获取矩阵的最大值及其下标统计单词个数
C语言三个数从小到大排序/输出
任意输入 3 个整数,编程实现对这 3 个整数由小到大进行排序。
int main(){int a,b,c,t; /*定义4个基本整型变量a、b、c、t*/printf("Please input a,b,c:\n"); /*双引号内的普通字符原样输出并换行*/scanf("%d,%d,%d",&a,&b,&c); /*输入任意3个数*/if(a>b) /*如果a大于b,借助中间变量t实现a与b值的互换*/{t = a;a = b;b = t;}if(a>c) /*如果a大于c,借助中间变景t实现a与c值的互换*/{t = a;a = c;c = t;}if(b>c) /*如果b大于c,借助中间变量t实现b与c值的互换*/{t = b;b = c;c = t;}printf("结果为:\n");printf("%d,%d,%d",a,b,c); /*输出函数顺序输出a、b、c的值*/return 0;}
C语言猴子吃桃问题
int main(){intday,x1,x2; /*定义 day、x1、x2 3 个变董为基本整型*/day=9;x2=1;while(day>0){x1=(x2+1)*2; /*第一天的桃子数是第二天桃子数加1后的2倍*/x2=x1;day--; /*因为从后向前推所以天数递减*/}printf("the total is %d\n",x1); /* 输出桃子的总数*/return 0;}
百钱买百鸡(百钱百鸡,百鸡问题)
中国古代数学家张丘建在他的《算经》中提出了一个著名的“百钱买百鸡问题”,鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何?
int main(){int cock,hen,chick; /*定义为基本整型*/for(cock=0;cock<=20;cock++) /*公鸡范围在 0~20 之间*/for(hen=0;hen<=33;hen++) /*母鸡范围在 0~33 之间*/for(chick=3;chick<=99;chick++) /*小鸡范围在 3~99 之间*/if(5*cock+3*hen+chick/3==100) /*判断钱数是否等于 100*/if(cock+hen+chick==100) /*判断购买的鸡数是否等于 100*/if(chick%3==0) /*判断小鸡数是否能被 3 整除*/printf("公鸡:%d,母鸡:%d,小鸡:%d\n",cock,hen,chick);return 0;}渔夫打鱼晒网问题
如果一个渔夫从 2011 年 1 月 1 日开始每三天打一次渔,两天晒一次网,编程实现当输入 2011 1 月 1 日以后的任意一天,输出该渔夫是在打渔还是在晒网。
int leap(int a) /*自定义函数leap()用来指定输入的年份是否为闰年*/{if (a%4==0&&a%100!=0||a%400==0) /* 闰年判定条件 */return 1; /*是闰年返回1*/elsereturn 0; /*不是闰年返回O*/}int number(int year,int month,int day) /*自定义函数 number() 计算输入日期距2011年1月1日共有多少天*/{int sum = 0, i, j, k;int a[12]={31,28,31,30,31,30,31,31,30,31,30,31}; /*数组a存放平年每月的天数*/int b[12]={31,29,31,30,31,30,31,31,30,31,30,31}; /*数组b存放闰年每月的天数*/if(leap(year)==1) /*判断是否为闰年*/for(i=0;i<month-1;i++)sum+=b[i]; /*是闰年,累加数组b前m-1个月份的天数*/elsefor(i=0;i<month-1;i++)sum+=a[i]; /*不是闰年,累加数组a前m-1个月份的天数*/for(j=2011;j<year;j++)if (leap(j)==i)sum+=366; /*2011年到输入的年份是闰年的加366*/elsesum+=365; /*2011年到输入的年份不是闰年的加365*/sum+=day; /*将前面累加的结果加上日期,求出总天数*/return sum; /*返回计算的天数*/}int main(){int year,month,day,n;printf("请输入年月日\n");scanf("%d%d%d",&year,&month,&day); /*输入年月日*/n=number(year,month,day); /*调用函数 number()*/if((n%5)<4&&(n%5)>0) /*余数是1或2或3时说明在打渔,否则在晒网*/printf("%d:%d:%d 打鱼\n",year,month,day);elseprintf("%d:%d:%d 晒网\n",year,month,day);return 0;}
希尔排序算法
int shsort(int s[], int n) /* 自定义函数 shsort()*/{int i,j,d;d=n/2; /*确定固定增虽值*/while(d>=1){for(i=d+1;i<=n;i++) /*数组下标从d+1开始进行直接插入排序*/{s[0]=s[i]; /*设置监视哨*/j=i-d; /*确定要进行比较的元素的最右边位置*/while((j>0)&&(s[0]<s[j])){s[j+d]=s[j]; /*数据右移*/j=j-d; /*向左移d个位置V*/}s[j + d]=s[0]; /*在确定的位罝插入s[i]*/}d = d/2; /*增里变为原来的一半*/}return 0;}int main(){int a[11],i; /*定义数组及变量为基本整型*/printf("请输入 10 个数据:\n");for(i=1;i<=10;i++)scanf("%d",&a[i]); /*从键盘中输入10个数据*/shsort(a, 10); /* 调用 shsort()函数*/printf("排序后的顺序是:\n");for(i=1;i<=10;i++)printf("%5d",a[i]); /*输出排序后的数组*/printf("\n");return 0;}
冒泡排序算法
用冒泡排序法对任意输入的 10 个数按照从小到大的顺序进行排序。
int main(){int i,j,t,a[11]; //定义变量及数组为基本整型printf("请输入10个数:\n");for(i=1;i<11;i++)scanf("%d",&a[i]); //从键盘中输入10个数for(i=1;i<10;i++) //变量i代表比较的趟数for(j=1;j<11-i;j++) //变最j代表每趟两两比较的次数if(a[j]>a[j+1]){t=a[j]; //产利用中间变童实现两值互换a[j]=a[j+1];a[j+1]=t;}printf("排序后的顺序是:\n");for(i=1;i<=10;i++)printf("%5d",a[i]); //将胃泡排序后的顺序输出printf("\n");return 0;}
直接插入排序算法
int insort(int s[], int n) /* 自定义函数 insort()*/{int i,j;for(i=2;i<=n;i++) //数组下标从2开始,s[0]做监视哨,s[1]一个数据无可比性{s[0]=s[i]; //给监视哨陚值j=i-1; //确定要比较元素的最右边位黄while(s[0]<s[j]){s[j+1]=s[j]; //数据右移j--; //产移向左边一个未比较的数}s[j+1]=s[0]; //在确定的位置插入s[i]}return 0;}int main(){int a[11],i; //定义数组及变量为基木整甩printf("请输入10个数据:\n");for (i =1;i<=10;i++)scanf("%d",&a[i]); //接收从键盘输入的10个数据到数组a中printf("原始顺序:\n");for(i=1;i<11;i++)printf("%5d",a[i]); //将未排序前的顺序输出insort(a,10); //调用自定义函数 insort()printf("\n 插入数据排序后顺序:\n");for(i=1;i<11;i++)printf("%5d",a[i]); //将排序后的数组输出printf("\n");return 0;}
快速排序算法
用快速排序法对一组数据由小到大进行排序,数据分别为 99、45、12、36、69、22、62、 796、4、696。
int qusort(int s[],int start,int end) //自定义函数 qusort(){int i,j; //定义变量为基本整型i=start; //将每组首个元素赋给ij = end; //将每组末尾元素赋给js[0]=s[start]; //设置基准值while(i<j){while(i<j&&s[0]<s[j])j--; //位置左移if(i<j){s[i]=s[j]; //将s[j]放到s[i]的位置上i++; //位置右移}while(i<j&&s[i]<=s[0])i++; //位置左移if(i<j){s[j]=s[i]; //将大于基准值的s[j]放到s[i]位置j--; //位置左移}}s[i]=s[0]; //将基准值放入指定位置if (start<i)qusort(s,start,j-1); //对分割出的部分递归调用qusort()函数if (i<end)qusort(s,j+1,end);return 0;}int main(){int a[11], i; //定义数组及变量为基本整型printf("请输入10个数:\n");for(i=1;i<=10;i++)scanf("%d",&a[i]); //从键盘中输入10个要进行排序的数qusort(a,1,10); //调用qusort()函数进行排序printf("排序后的顺序是:\n");for(i=1;i<=10;i++)printf("%5d",a[i]); //输出排好序的数组printf("\n");return 0;}
选择排序算法
int main(){int i,j,t,a[11]; //定义变量及数组为基本整型printf("请输入10个数:\n");for(i=1;i<11;i++)scanf("%d",&a[i]); //从键盘中输入要排序的10个数字for(i=1;i<=9;i++)for (j=i+1;j<=10;j++)if(a[i]>a[j]) //如果前一个数比后一个数大,则利用中间变量t实现两值互换{t=a[i];a[i]=a[j];a[j]=t;}printf("排序后的顺序是:\n");for(i=1;i<=10;i++)printf("%5d", a[i]); //输出排序后的数组printf("\n");return 0;}
归并排序算法
用归并排序法对一组数据由小到大进行排序,数据分别为 695、458、362、789、12、 15、163、23、2、986。
int merge(int r[],int s[],int x1,int x2,int x3) //自定义实现一次归并样序的函数{int i,j,k;i=x1; //第一部分的开始位置j=x2+1; //第二部分的开始位置k=x1;while((i<=x2)&&(j<=x3)) //当i和j都在两个要合并的部分中时if(r[i]<=r[j]) //筛选两部分中较小的元素放到数组s中{s[k] = r[i];i++;k++;}else{s[k]=r[j];j++;k++;}while(i<=x2) //将x1〜x2范围内未比较的数顺次加到数组r中s[k++]=r[i++];while(j<=x3) //将x2+l〜x3范围内未比较的数顺次加到数组r中s[k++]=r[j++];return 0;}int merge_sort(int r[],int s[],int m,int n){int p;int t[20];if(m==n)s[m]=r[m];else{p=(m+n)/2;merge_sort(r,t,m,p); //递归调用merge_soit()函数将r[m]〜r[p]归并成有序的t[m]〜t[p]merge_sort(r,t,p+1,n); //递归一调用merge_sort()函数将r[p+l]〜r[n]归并成有序的t[p+l]〜t[n]merge(t,s,m,p,n); //调用函数将前两部分归并到s[m]〜s[n】*/}return 0;}int main(){int a[11];int i;printf("请输入10个数:\n");for(i=1;i<=10;i++)scanf("%d",&a[i]); //从键盘中输入10个数merge_sort(a,a,1,10); //调用merge_sort()函数进行归并排序printf("排序后的顺序是:\n");for(i=1;i<=10;i++)printf("%5d",a[i]); //输出排序后的数据printf("\n");return 0;}
二分查找算法,折半查找算法
int binary_search(int key,int a[],int n) //自定义函数binary_search(){int low,high,mid,count=0,count1=0;low=0;high=n-1;while(low<high) //査找范围不为0时执行循环体语句{count++; //count记录査找次数mid=(low+high)/2; //求中间位置if(key<a[mid]) //key小于中间值时high=mid-1; //确定左子表范围else if(key>a[mid]) //key 大于中间值时low=mid+1; //确定右子表范围else if(key==a[mid]) //当key等于中间值时,证明查找成功{printf("查找成功!\n 查找 %d 次!a[%d]=%d",count,mid,key); //输出査找次数及所査找元素在数组中的位置count1++; //count1记录查找成功次数break;}}if(count1==0) //判断是否查找失敗printf("查找失敗!"); //査找失敗输出no foundreturn 0;}int main(){int i,key,a[100],n;printf("请输入数组的长度:\n");scanf("%d",&n); //输入数组元素个数printf("请输入数组元素:\n");for(i=0;i<n;i++)scanf("%d",&a[i]); //输入有序数列到数组a中printf("请输入你想查找的元素:\n");scanf("%d",&key); //输入要^找的关键字binary_search(key,a,n); //调用自定义函数printf("\n");return 0;}
分块查找算法,索引顺序查找算法
例如,采用分块查找法在有序表 11、12、18、28、39、56、69、89、96、122、135、146、156、256、298 中查找关键字为 96 的元素。
査找特定关键字元素个数为 15,要求用户输入有序表各元素,程序输出査找成功与否,若成功,还显示元素在有序表中的位罝。
struct index //定义块的结构{int key; //块的关键字int start; //块的起始值int end; //块的结束值}index_table[4]; //定义结构体数组int block_search(int key,int a[]) //自定义实现分块查找{int i,j;i=1;while(i<=3&&key>index_table[i].key) //确定在哪个块中i++;if(i>3) //大于分得的块数,则返回0return 0;j=index_table[i].start; //j等于块范围的起始值while(j<=index_table[i].end&&a[j]!=key) //在确定的块内进行顺序查找j++;if(j>index_table[i].end) //如果大于块范围的结束值,则说明没有要査找的数,j置0j = 0;return j;}int main(){int i,j=0,k,key,a[16];printf("请输入15个数:\n");for(i=1;i<16;i++)scanf("%d",&a[i]); //输入由小到大的15个数for(i=1;i<=3;i++){index_table[i].start=j+1; //确定每个块范围的起始值j=j+1;index_table[i].end=j+4; //确定每个块范围的结束值j=j + 4;index_table[i].key=a[j]; //确定每个块范围中元素的最大值}printf("请输入你想査找的元素:\n");scanf("%d",&key); //输入要查询的数值k=block_search(key,a); //调用函数进行杳找if(k!=0)printf("查找成功,其位置是:%d\n",k); //如果找到该数,则输出其位置elseprintf("查找失败!"); //若未找到,则输出提示信息return 0;}
求n的阶乘(n!)
int main(){int i,n;double sum=1;scanf("%d",&n);for(i=1;i<=n;i++)sum=sum*i;printf("%d!=%lf",n,sum);printf("\n");return 0;}
判断三角形的类型
根据输入的三角形的三条边判断三角形的类型,并输出其面积和类型。
int main(){float a,b,c;float s,area;printf("请输入三角形的三条边:\n");scanf("%f,%f,%f",&a,&b,&c);if(a+b>c&&b+c>a&&a+c>b){s=(a+b+c)/2;area=(float)sqrt(s*(s-a)*(s-b)*(s-c));printf("三角形的面积是:%f\n" ,area);if(a==b&&a==c)printf("三角形是等边三角形\n");else if(a==b||a==c||b==c)printf("三角形是等腰三角形\n");else if((a*a+b*b==c*c)||(a*a+c*c==b*b)||(b*b+c*c==a*a))printf("三角形是直角三角形\n");elseprintf("三角形是普通三角形\n");}elseprintf("不能构成三角形\n");return 0;}
水仙花数,阿姆斯特朗数
int main(){int i,j,k,n;for(i=100;i<1000;i++){j=i%10;k=i/10%10;n=i/100;if(j*j*j+k*k*k+n*n*n==i)printf("%5d\n",i);}return 0;}
最大公约数和最小公倍数
从键盘输入两个正整数 a 和 b,求其最大公约数和最小公倍数。
#include <stdio.h>int main(){int a,b,c,m,t;printf("请输入两个数:\n");scanf("%d%d",&a,&b);if(a<b){t=a;a=b;b=t;}m=a*b;c=a%b;while(c!=0){a=b;b=c;c=a%b;}printf("最大公约数是:\n%d\n",b);printf("最小公倍数是:\n%d\n",m/b);}
求自然底数e,求自然对数的底e
e=1+1/1!+1/2!+1/3!+…
要求当最后一项的值小于 10-10 时结束。
int main(){float e=1.0,n=1.0;int i=1;while(1/n>1e-10){e+=1/n;i++;n=i*n;}printf("e的值是:%f\n",e);return 0;}
小写转大写,小写字母转换成大写字母
在 C 语言中区分字母的大小写,利用 ASCII 码中大写字母和小写字母之间的转换关系(差值为 32),可以将小写字母转换为大写字母。编写程序实现,从键盘上输入一个小写字母,按回车键,程序将该小写字母转换为大写字母,并输出其 ASCII 值。
int main(){char a,b;printf("输入一个小写字母:\n");a=getchar();b=a-32;printf("转换后的字母为:%c,%d\n",b,b);return 0;}
求回文素数
#include <stdio.h>int sushu(int i){int j;if(i<=1)return 0;if(i==2)return 1;for(j=2;j<i;j++){if(i%j==0)return 0;else if(i!=j+1)continue;elsereturn 1;}}int main(){int i;for(i=10;i<1000;i++)if(sushu(i)==1)if(i/100==0){if(i/10==i%10)printf("%5d",i);if(i%5==0)printf("\n");}elseif(i/100==i%10)printf("%5d",i);if(i%5==0)printf("\n");return 0;}
判断闰年,即判断年份是否为闰年
实例要求从键盘输入任意年份的整数 N,通过程序运行判断该年份是否为闰年。
#include <stdio.h>int main(){int year,a;printf("请输人年份:\n");scanf("%d",&year);if(year%400==0)a=1;else{if(year%4==0&&year%100!=0)a=1;elsea=0;}if(a==1){printf("%d 此年是闰年\n",year);}else{printf("%d 此年非闰年\n",year);}return 0;}
矩阵转置
设有一矩阵为 m×n 阶(即 m 行 n 列),第 i 行 j 列的元素是 a(i,j),需要将该矩阵转置为 n×m 阶的矩阵,使其中元素满足 b(j,i)=a(i,j)。
int main(){int i,j,i1,j1,a[101][101],b[101][101];printf("please input the number of rows(<=100)\n");scanf("%d",&i1);printf("please input the number of columns(<=100)\n");scanf("%d",&j1);printf("please input the element\n");for(i=0;i<i1;i++)for(j=0;j<j1;j++)scanf("%d",&a[i][j]);printf("array a:\n");for(i=0;i<i1;i++){for(j=0;j<j1;j++)printf("\t%d",a[i][j]);printf("\n");}for(i=0;i<i1;i++)for(j=0;j<j1;j++)b[j][i]=a[i][j];printf("array b:\n");for(i=0;i<j1;i++){for(j=0;j<i1;j++)printf("\t%d",b[i][j]);printf("\n");}return 0;}
兔子生兔子问题
假设一对兔子的成熟期是一个月,即一个月可长成成兔,那么,如果每对成兔每个月都生一对小兔,一对新生的小兔从第二个月起就开始生兔子,试问从一对兔子开始繁殖,以后每个月会有多少对兔子?
int main(){int i,tu1,tu2,tu3,m;tu1=1;tu2=1;printf("请输入月份数\n");scanf("%d",&m);if(m==1||m==2){printf("有一对兔子");}else if(m>2){for(i=3;i<=m;i++){tu3=tu1+tu2;tu1=tu2;tu2=tu3;}printf("%d 月的兔子数为:%d\n",m,tu3);}return 0;}
狼追兔子问题
int main(){int i;bool pos[10]={0};int lang=0;for(i=0;i<100;i++){pos[lang]=true;lang++;lang+=i;lang=lang%10;}for(i=0;i<10;i++)if(!pos[i])printf("兔子可能在第%d洞中\n",i+1);return 0;}
谁家孩子跑得最慢
张、王、李三家各有三个小孩。一天,三家的九个孩子在一起比赛短跑,规定不分年龄大小,跑第一得 9 分,跑第二得 8 分,依次类推。比赛结果显示各家的总分相同,且这些孩子没有同时到达终点的,也没有一家的两个或三个孩子获得相连的名次。已知获第一名的是李家的孩子,获第二名的是王家的孩子。获得最后一名的是谁家的孩子?
int score[4][4];int main(){int i,j,k,who;score[1][1]=7;score[2][1]=8;score[3][1]=9;for(i=4;i<6;i++)for(j=4;j<7;j++)for(k=4;i!=j&&k<7;k++)if(k!=i&&k!=j&&15-i-score[1][1]!=15-j-score[2][1]&&15-i-score[1][1]!=15-k-score[3][1]&&15-j-score[2][1]!=15-k-score[3][1]){score[1][2]=i;score[1][3]=15-i-7;score[2][2]=j;score[2][3]=15-j-8;score[3][2]=k;score[3][3]=15-k-9;}for(who=0,i=1;i<=3;i++,printf("\n"))for(j=1;j<=3;j++){printf("%d",score[i][j]);if(score[i][j]==1)who=i;}if(who==1)printf("最后一名是张家孩子\n");else if(who==2)printf("最后一名是王家孩子\n");elseprintf("最后一名是李家孩子\n");return 0;}
获取矩阵的最大值及其下标
int main(){int a[3][4],i,j,max,max_i=0,max_j=0;for(i=0;i<3;i++)for(j=0;j<4;j++)scanf("%d",&a[i][j]);max=a[0][0];for(i=0;i<3;i++)for(j=0;j<4;j++)if(a[i][j]>max){max=a[i][j];max_i=i;max_j=j;}printf("max=a[%d][%d]=%d\n",max_i,max_j,max);return 0;}
统计单词个数,单词个数算法
在实际生活中经常会遇到一个问题:写英语作文时,常常要求满足一定的字数。在以往,要么我们一个一个地数;要么我们估算一行的单词数,然后用行数进行估算。
第一种方法太费时,若是长篇大论,那几乎是不可能统计的;而第二种方法不太准确。这就给我们留下了一个问题:如何又快、又准确地统计一篇英文文章中的单词数?
int main(){printf("输入一行字符:\n");char ch;int i,count=0,word=0;while((ch=getchar())!='\n')if(ch==' ')word=0;else if(word==0){word=1;count++;}printf("总共有 %d 个单词\n",count);return 0;}
