一:基础算法原理
1. 冒泡排序
原理:从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。
以从小到大排序为例,第一轮比较后,所有数中最大的那个数就会浮到最右边;第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到大排序。
这里按六个数做代码演示 for(int i=1;i<6;i++){for(int j=0;j<6-i;j++){if(a[j]>a[j+1]){a[j]与a[j+1]调换位置}} }
2. 选择排序
原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
这里按6个数做代码演示 int i,j; for (i=0; i<6; i++){for (j=i+1;j<6;j++){if (a[i]>a[j]){交换两数位置}} {
3. 求最大公约数和最小公倍数
求m和n的最大公约数,m%n=c 若c=0则出任n为两数的最大公约数,若c不等于0,则m=n,n=c
再继续执行while直到c=0
最小公倍数是: 两数乘积/最大公约数
#include <stdio.h>
void main(){int m,n,c,p,q; scanf("%d,%d",&m,&n); q=m*nif(m<n){p=m;m=n;n=p 让m为两者中最大的数}while(n!=0){c=m%n;m=n;n=c;}printf("最大公约数是%d",m)printf("最小公倍数是%d",q/m)
}
二: 编程题
1、鸡兔同笼:35 个头,94 只脚,问鸡兔各多少?
#include <stdio.h>
void main(){int rabbit,chicken;for(rabbit=1;rabbit<=23;rabbit++){chicken=35-rabbit;if(rabbit*4+chicken*2==94)printf("r=%d,c=%d\n",rabbit,chicken);}
}
2、从键盘录入一串字符(个数不定,遇到'#'结束)到一维字符数组,统计大写字母和小写字母的个数
#include <stdio.h>
void main(){char c;int len=0;while((c=getchar())!='#') if(c>='A'&&c<='Z' || c>='a'&&c<='z') len++;printf("字母个数为%d",len);
}
3、输入一个正整数,判素数即素数显示"x 是素数",不是素数显示"x 非素数"。 说明:1 不是素数,2 是素数,x 即输入的数
#include <stdio.h>
void main(){int x,i,flag=1;scanf("%d",&x);if(x==1) printf("非素数");else if(x==2) printf("非素数");else{for(i=2;i<x;i++)if(x%i==0){flag=0;break;}if (flag)printf("%d 是素数",x);elseprintf("%d 非素数",x);}
}
4、求数列 1!+2!+3!+4!+5!的和
#include <stdio.h>
int main(){int sum=0,i,k=1;for(i=1;i<=5;i++){k=k*i;sum+=k;}printf("sum=%d",sum);
}
5、π/4 =1-1/3+1/5-1/7+... 求π值,直到最后一项的绝对值小于10的-6次方 为止
#include <stdio.h>
#include <math.h>
void main(){float sum=0,item=1,sign=1,fm=1;while(fabs(item)>=1e-5){sum+=item;sign = -sign;fm+=2;item = 1/fm*sign;}printf("%f",sum*4);
}
6、用下面的公式求 e x的近似值,直到最后一项小于 10的-6次方为止。
#include <stdio.h>
void main(){float sum=1,item,fm,x,fz,i=1;scanf("%f",&x);fz=x,fm=1;item = fz/fm;while(item>=1e-6){sum+=item;fz=fz*x;i++,fm=fm*i;item = fz/fm;}printf("%f",sum);
}
7、输入 x,计算多项式 1 - x + x*x / 2!- x*x*x / 3!+ ...的和,直到末项的绝对值小于 10 的 - 6 次方为止
#include <stdio.h>
#include <math.h>
void main(){float sum=1,item,sign=-1,fm,x,fz,i=1;scanf("%f",&x);fz=x,fm=1;item = fz/fm*sign;while(fabs(item)>=1e-6){sum+=item;sign = -sign;fz=fz*x;i++,fm=fm*i;item = fz/fm*sign;}printf("%f",sum);
}
8、计算 1 到几的累加和正好大于 5050 。
#include <stdio.h
void main(){int i =0, sum = 0;while (sum<=5050){i++;sum += i;}printf("i=%d\n", i);
}
9、一维整型数值数组,大小为 10,通过键盘输入数据,求最大值并输出
#include <stdio.h>
void main(){int a[10],i,max;for(i=0;i<10;i++) scanf("%d",&a[i]);max=a[0];for(i=1;i<10;i++){if(max<a[i]) max=a[i];}printf("最大值为%d",max);
}
10、一维实型数值数组,大小为 10,通过键盘输入数据,求平均值并输出
#include <stdio.h>
void main(){int i;float a[10],sum=0;for(i=0;i<10;i++) scanf("%f",&a[i]);for(i=0;i<10;i++){sum+=a[i];}printf("平均值为%f",sum/10);
}
11、一维整型数值数组,大小为 10,通过键盘输入数据,升序排列并输出。
#include <stdio.h>
void main(){int i,j, a[10],temp;for(i=0;i<10;i++) scanf("%d",&a[i]);for(i=1;i<10;i++){for(j=0;j<10-i;j++){if(a[j]>a[j+1]){temp=a[j];a[j]=a[j+1];a[j+1]=temp;}}}for(i=0;i<10;i++) printf("%d\t",a[i]);
}
12、一维整型数值数组,大小为 10,通过键盘输入数据,逆序存放并输出
#include <stdio.h>
void main(){int a[10] , i,j, temp;for(i=0;i<10;i++) scanf("%d",&a[i]);for (i = 0,j=9; i<j; i++,j--){temp = a[i];a[i] = a[j];a[j] = temp;}for(i=0;i<10;i++) printf("%d\t",a[i]);
}
13、从键盘录入一串字符(<100,可含空格,回车结束)到一维字符数组,求串长
#include <stdio.h>
#include <string.h>
void main(){char ch[100];int i=0,len=0;gets(ch);while(ch[i]!='\0'){len++;i++;}printf("长度为%d",len);
}
14、编写程序,用冒泡法将从键盘上输入的 10 个整数按升序排序。请将程序补充完整。 所谓冒泡法排序就是相邻的两个元素比较,有反序则交换。 【说明:变量 i 用于控制排序趟数,变量 j 用于相邻的两数比较,变量 t 用于交换相邻的两 个整数,变量 flag=1 说明还要进行下一趟排序,flag=0 提前结束排序过
#include <stdio.h>
void main(){ int a[10],i,j,t,flag=1;for(i=0;i<10;i++)scanf("%d",a+i);for(i=1;flag&&i<10;i++){ flag=0;for(j=0;j<10-i;j++)if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;flag=1;}}for(i=0;i<10;i++)printf("%5d",a[i]);printf("\n");
}
15、编写函数实现字符串求长
#include <stdio.h>
int strlen(char a[]){int i=0;while(a[i]) i++;return i;
}
int main(){char ch[100];gets(ch);printf("长度为%d",strlen(ch));
}
16、编写程序将字符串a复制为字符串b。要求用数组完成。
#include <stdio.h>
void main(){char a[ ],b[20];int i;gets(a);for(i=0;*(a+i)!='\0';i++) *(b+i)=*(a+i); *(b+i)='\0';printf("string a is:%s\n",a);printf("string b is:");for(i=0;b[i]!='\0';i++) printf("%c",b[i]);printf("\n");
}
17、编写程序将字符串a复制为字符串b。要求用指针变量完成。
#include <stdio.h>
void main(){char a[],b[20],*p1,*p2;int i;p1=a;p2=b;gets(p1);for(;*p1!='\0';p1++,p2++) *p2=*p1;*p2='\0';printf("string a is:%s\n",a);printf("string b is:");for(i=0;b[i]!='\0';i++) printf("%c",b[i]);
}
18、用函数调用实现字符串的复制。要求用指针变量实现。
#include <stdio.h>
void main(){ void copy_string(char *from, char *to);char *a="I am a teacher.";char b[]="You are a student.";char *p=b;printf("string a=%s\nstring b=%s\n",a,p);copy_string(a,p);printf("\nstring a=%s\nstring b=%s\n",a,b);
}
void copy_string(char *from, char *to){ for(;*from!='\0';from++,to++){*to=*from;}*to='\0';
}
19、字符串连接—用字符数组编程
#include <stdio.h>
void MyStrcat(char dstStr[], char srcStr[]){int i = 0,j=0;while(dstStr[i]!='\0') i++;while (srcStr[j] != '\0') {dstStr[i] = srcStr[j];i++; j++;}dstStr[i] = '\0';
}
int main(){ char a[20]="abc",b[]="xy";MyStrcat(a,b);printf("%s ",a);return 0;
}
20、字符串连接—用指针编程
#include <stdio.h>
void MyStrcat(char *dstStr, char *srcStr){char *p,*q;p=dstStr; q=srcStr;while(*p!='\0') p++;while (*q != '\0') {*p=*q;p++; q++;}*p = '\0';
}
int main(){char a[20]="abc",b[]="xy";MyStrcat(a,b);printf("%s ",a);return 0;
}
21、用指针方式编写函数 mystrcmp(char *,char *),实现字符串的比较。
include <stdio.h>
int mystrcmp ( char *s,char *t){while (*s == *t){if (*s =='\0') return 0;s++; t++;}return (*s- *t);
}
void main(){char *pa="CHINA",b[10]="CANADA",*pb;pb=b;if(mystrcmp(pa,pb)>0)printf("%s > %s\n",pa,pb);else if(mystrcmp(pa,pb)==0)printf("%s = %s\n",pa,pb);else printf("%s < %s\n",pa,pb);
}
22、编写函数 fib 求斐波那契数列第 n 项的值,并在主函数中调用 fib 输出斐数列前 20 项 的值,每 5 个一行显示。要求用递归方法实现。
#include <stdio.h>
int fib(int n){static int f1=1,f2=0;int f3;f3=f1+f2;f1=f2;f2=f3;return f3;
}
int main(){int i;for (i = 1; i <= 20; i++){printf("%d\t", fib(i));if (i % 5 == 0) printf("\n");}
}
23、编一个程序,输入 100 个学生的百分制成绩,输出相应的五分制成绩。设成绩 90 分以 上为 A,80-89 为 B,70-79 为 C,60-69 为 D,60
#include <stdio.h>
void main(){int score;scanf("%d",&score);if(score<0 || score>100) printf("输入成绩错误!\n");else if(score>=90) printf("A");else if(score>=80) printf("B");else if(score>=70) printf("C");else if(score>=60) printf("D");else printf("E");
}
24、编一个程序,输入 100 个学生的百分制成绩,输出相应的五分制成绩。设成绩 90 分以 上为 A,80-89 为 B,70-79 为 C,60-69 为 D,60 分以下为 E。(用 switch 实现)
#include <stdio.h>
void main() {int score;scanf("%d",&score);if(score<0 || score>100) printf("输入成绩错误!\n");elseswitch(score/10){case 9:printf("A");break;case 8:printf("B");break;case 7:printf("C");break;case 6:printf("D");break;default:printf("E");break;}
}
25、现在 90 号汽油 6.95 元/升,93 号汽油 7.44 元/升,97 号汽油 7.93 元/升,为了吸引顾客 某自动加油站推出了自助服务和协助服务两个服务等级,分别可得到 5%和 3%的折扣。编 写程序,根据输入顾客的加油量 a,汽油品种 b(90、93、97)和服务类型 c(m-自助;e-协助), 计算并输出应付款。
#include <stdio.h>
void main (){float fee,money;int a,b;char c;scanf("%d%d%c",&a,&b,&c);switch(b){case 90: money=6.95;break;case 93: money=7.44;break;case 97: money=7.93;break;}if(c=='m')fee=money*a-money*a*0.05;elsefee=money*a-money*a*0.03;printf("%.2f\n",fee);
}
26、程序功能:从键盘上输入 10 名学生的 4 门课成绩,求每个学生的平均成绩,并分别统计每个学生的不及格门数,输出格式如下:张三平均分 xx.xx(2 位小数),不及格门数:2
#include <stdio.h>
typedef struct{char name[10];float score[4],avg;int num=0;
}Stu;
void main(){Stu stus[10];float sum=0;int i,j;for(i=0;i<10;i++){scanf("%s",stus[i].name);sum=0;for(j=0;j<4;j++){scanf("%f",&stus[i].score[j]);sum+=stus[i].score[j];if (stus[i].score[j]<60) stus[i].num++;}stus[i].avg=sum/4;}for(i=0;i<10;i++)printf("%s 平均分%.2f,不及格门数:%d\n",stus[i].name,stus[i].avg,stus[i].num);
}
27、编写函数,判断一个正整数是否为完数。 完数:一个数如果恰好等于它的因子之和,称该数为“完数”。1 不是完数。 如 6=1+2+3,则 6 为完数
int ws(int x){int i,sum=1;if(x==1)return 0;else{for(i=1;i<x;i++)if(x%i==0) sum+=i;if(sum==x) return 1;else return 0;}
}
28、编写函数判断正整数 n 是否为完全平方数。 完全平方数:设 sqrt(x)为 y,满足 y*y==x 则称 x 为完全平方数。如 16 为完全平方数;
int wqpf(int x){int y = sqrt(x);if (y*y == x)return 1;elsereturn 0;
}
29、编写函数,求两个正整数的最大公约数。 说明:两数的最大公约数一定小于等于较小的那个数,同时能被这两个数整除。
int maxGy(int m,int n){int r;if(m<n){r=m;m=n;n=r;}while(n!=0){r=m%n;m=n;n=r;}return m;
}
30、有一批图书(50 本),每本书信息包括书名(name),作者(author) ,价格(price-整数)三 个数据,现要实现如下 2 个任务: ① 输入书籍信息并按价格降序排序,供以后查询。 ② 实现数据查询,输入一本书的书名,如果查询到库中有此书,打印出此书的作者;如果 查不到此书,则打印出"无此书"。
#include <stdio.h>
#include <string.h>
#define N 50
typedef struct{char name[10],author[10];int price;
}Book;
void main (){Book bs[N],temp;char name[10];int i,j;for(i=0;i<N;i++) scanf("%s %s %d",bs[i].name, bs[i].author,&bs[i].price);for(i=1;i<N;i++){for(j=0;j<N-i;j++){if(bs[j].price<bs[j+1].price){temp=bs[j];bs[j]=bs[j+1];bs[j+1]=temp;}}}printf("输入要查询的书籍名:");scanf("%s",name);for(i=0;i<N;i++)if(strcmp(bs[i].name,name)==0){printf("%s 的作者是%s",bs[i].name,bs[i].author);break;}if(i==N) printf("%s 不在库中",name);
}
31、分别打印 2 种直角三角形,如图
#include <stdio.h>
void main(){int i,j;for(i=1;i<=4;i++){for(j=1;j<=i;j++) printf("*");printf("\n");}for(i=1;i<=4;i++){for(j=1;j<=2*i-1;j++) printf("*");printf("\n");}
}
32、打印九九乘法表
#include <stdio.h>
void main(){int i,j;for(i=1;i<=9;i++){for(j=1;j<=i;j++){printf("%d*%d=%d\t",j,i,j*i);}printf("\n");}
}
33、用非递归方式编写函数 strlength()。该函数与库函数 strlen()功能相同,返回参数字符串 的长度(整型),不允许调用任何库函数。
#include "stdio.h"
int strlength(char *p){int k=0;while(*p!='\0'){ k++; p++; }return k;
}
int main(){char a[10];int k=0;gets(a);k=strlength(a);printf("%d",k);return 0;
}
34、用递归方式编写函数 strlength()。该函数与库函数 strlen()功能相同,返回参数字符串的 长度(整型),不允许调用任何库函数
#include "stdio.h"
int strlength(char *a){int b=0;if(*a=='\0') b=0;else b=1+strlength(a+1);return b;
}
int main(){char a[10];int k=0;gets(a);k=strlength(a);printf("%d",k);return 0;
}
35、有5个人坐在一起,问第5个人多少岁?他说比第4个人大2岁。问第4个人岁数, 他说比第3个人大2岁。问第3个人,又说比第2个人大2岁。问第2个人,说比第1个 人大2岁。最后问第1个人,他说是10岁。请问第5个人多大。
#include <stdio.h>
int age(int n){ int c;If(n==1) c=10;else c=age(n-1)+2;return c;
}
void main(){printf(″%d″,age(5));
}
36、有两个数组a和b,各有10个元素,将它们对应地逐个相比(即a[0]与b[0] 比,a[1]与b[1]比……)。如果a数组中的元素大于b数组中的相应元素的数目多 于 b 数组中元素大于 a 数组中相应元素的数目,则认为 a 数组大于 b 数组,并分别统计出 两个数组相应元素大于、等于、小于的次数。
#include <stdio.h>
void main(){int large(int x,int y);int a[10],b[10],i,n=0,m=0,k=0;for(i=0;i<10;i++) scanf("%d",&a[i]);for(i=0;i<10;i++) scanf("%d",&b[i]);for(i=0;i<10;i++){if(large(a[i],b[i])==1) n++;else if(large(a[i],b[i])==0)m++;else k++;}printf("a[i]>b[i] %d times\na[i]=b[i] %d times\na[i]<b[i] %d times\n",n,m,k);if(n>k) printf("array a is larger than array b\n");else if (n<k) printf("array a is smaller than array b\n");elseprintf("array a is equal to array b\n");
}
int arge(int x,int y){int flag;if(x>y)flag=1;else if(x<y)flag=-1;else flag=0;return(flag);
}
37、有一个一维数组 score,内放 10 个学生成绩,求平均成绩。要求:计算平均值用子函 数完成。
#include <stdio.h>
void main(){ float average(float array[10]);float score[10],aver;int i;printf("input 10 scores:\n");for(i=0;i<10;i++)scanf("%f",&score[i]);printf("\n");aver=average(score);printf("average score is %5.2f\n",aver);
}
float average(float array[10]){int i;float aver,sum=0;for(i=0;i<10;i++)sum=sum+array[i];aver=sum/10;return(aver);
}
38、有 3 个字符串,要求找出其中最大者
#include<stdio.h>
#include<string.h>
void main ( ){char string[20];char str[3][20];int i;for (i=0;i<3;i++)gets (str[i]);if (strcmp(str[0],str[1])>0)strcpy(string,str[0]);else strcpy(string,str[1]);if (strcmp(str[2],string)>0)strcpy(string,str[2]);printf("\nthe largest string is:\n%s\n",string);
}
39、将若干字符串按字母顺序(由小到大)输出。
#include <stdio.h>
#include <string.h>
void main(){void sort(char *name[ ],int n);void print(char *name[ ],int n);char *name[ ]={"Follow me","BASIC","Great Wall","FORTRAN","Computer design"};int n=5;sort(name,n);print(name,n);
}
void sort(char *name[ ],int n){char *temp;int i,j,k;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0) k=j;if(k!=i){temp=name[i]; name[i]=name[k];name[k]=temp; }}
}
void print(char *name[ ],int n){int i;for(i=0;i<n;i++)printf("%s\n",name[i]);
}
40、爱因斯坦出了一道这样的数学题:有一条长阶梯,若每步跨 2 阶,则最后剩一阶;若 每步跨 3 阶,则最后剩 2 阶;若每步跨 5 阶,则最后剩 4 阶;若每步跨 6 阶则最后剩 5 阶; 只有每次跨 7 阶,最后才正好一阶不剩。请问这条阶梯共有多少阶?
#include <stdio.h>
int main(){int n=0;while(1){if(n%2==1 && n%3==2 && n%5==4 && n%6==5 && n%7==0){printf("长度为%d",n);break;}elsen++;}
}
41、运输公司对用户计算运费。 路程(s,单位为km )越远,每公里运费越低。标准如下: s<250 没有折扣 250≤s<500 2%折扣 500≤s<1000 5%折扣 1000≤s<2000 8%折扣 2000≤s<3000 10%折扣 3000≤s15%折扣设每公里每吨货物的基本运费为p,货物重为w,距离为s,折扣为d,则总运费f的计 算公式为:f=p*w*s*(1-d)
#include <stdio.h>
void main ( ){int c,s;float p,w,d,f;scanf("%f,%f,%d",&p,&w,&s);if(s>=3000)c=12;else c=s/250;switch(c){case 0:d=0;break;case 1:d=2;break;case 2:case 3:d=5;break;case 4:case 5:case 6:case 7:d=8;break;case 8:case 9:case 10:case 11:d=10;break;case 12:d=15;break; }f=p*w*s*(1-d/100.0);printf("freight=%10.2f\n",f);
}
42、求ax 2+bx+c=0方程的解。 基本的算法: ① a=0,不是二次方程。 ② b 2-4ac=0,有两个相等实根。 ③ b 2 -4ac>0,有两个不等实根。
#include <stdio.h>
#include <math.h>
void main ( ){float a,b,c,disc,x1,x2;scanf("%f,%f,%f",&a,&b,&c);printf("the equation ");if(fabs(a)<=1e-6)printf("is not a quadratic\n");else{disc=b*b-4*a*c;if(fabs(disc)<=1e-6)printf("has two equal roots:%8.4f\n",-b/(2*a));else if(disc>1e-6){x1=(-b+sqrt(disc))/(2*a);x2=(-b-sqrt(disc))/(2*a);printf("has distinct real roots:%8.4f and %8.4f\n",x1,x2);}}
}