一:基础算法原理
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*n
if(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);
else
printf("%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");
else
switch(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;
else
fee=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;
else
return 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");
else
printf("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;
}else
n++;
}
}
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);
}
}
}