C语言的一小步—————— 一些小项目及解析
——--------
仅以此献给东半球第二优秀的C语言老师,黑锤李某鸽,希望总有那么一天我们的知识可以像他的丰臀一样渊博!
bug跟蚊子的相似之处:
1、不知道藏在哪里。
2、不知道有多少。
3、总是在你即将睡觉休息的时候出现。
基础练习 基础练习 基础练习 基础练习 基础练习 基础练习
1 //1、(课堂)编写程序,输出“XXX欢迎来到动物园!”(XXX是自己的名字)。 2 3 #include<stdio.h> 4 #define N 20 5 int main(){ 6 char ch[N]={0}; 7 scanf("%s",ch); 8 printf("%s欢迎来到动物园",ch); 9 10 11 //} 12 13 return 0; 14 }
1 //2、(课堂)打印用*组成的字母C 2 #include<stdio.h> 3 4 int main(){ 5 6 printf(" ***\n"); 7 printf(" * *\n"); 8 printf("*\n"); 9 //printf("*\n"); 10 printf("*\n"); 11 printf(" * *\n"); 12 printf(" ***\n"); 13 return 0; 14 }
1 #if 0 2 交换杯子里的液体。使用不同的整数代表液体,变量代表杯子。 3 (课堂)方法1:中间变量法 4 (课堂)方法2:三步异或法 5 #endif 6 7 #include<stdio.h> 8 9 void fun1(int *i,int *j){ 10 int temp; 11 temp=*i; 12 *i=*j; 13 *j=temp; 14 15 } 16 void fun2(int *i,int *j){ 17 *i^=*j; 18 *j^=*i; 19 *i^=*j; 20 } 21 int main(){ 22 23 int i=3,j=9; 24 printf("i=%d,j=%d\n",i,j); 25 fun1(&i,&j); 26 printf("i=%d,j=%d\n",i,j); 27 fun2(&i,&j); 28 printf("i=%d,j=%d\n",i,j); 29 30 return 0; 31 }
1 //4、(课堂)使用宏定义PI来定义3.1415926,计算圆的面积。 2 #include<stdio.h> 3 #define PI 3.1415926 4 int main(){ 5 int length,perimiter; 6 printf("输入半径:"); 7 scanf("%d",&length); 8 perimiter=length*2*PI; 9 printf("周长:%d",perimiter); 10 }
1 #if 0 2 5、(课堂)租船问题。 3 写程序计算游客需要付的租船的费用。租船每小时30元。游客输入租船时间,计算出租船费用。租船费用=时间*每小时钱数+押金。 4 要求押金与每小时钱数使用宏定义。 5 #endif 6 #include<stdio.h> 7 #define unit 30 8 #define deposite 100 9 10 11 int main(){ 12 int time,total; 13 printf("请输入时间"); 14 scanf("%d",&time); 15 total=time*unit+deposite; 16 printf("总价:%d",total); 17 return 0; 18 }
1 #if 0 2 7_1、输入整数代表的ASCII码字符,输出这个一个整数(0~255)。 3 解题思路: 4 以%c形式输入以%d形式输出 5 以%d形式输入以%c形式输出 6 7 错误分析: 8 如果scanf()和printf()交替出现 9 则第二次scanf()时会首先输出前一次最后的回车。 10 11 getchar()的用处去除回车, 12 13 #endif 14 #include<stdio.h> 15 16 int main(){ 17 char ch; 18 int a; 19 while(1){ 20 printf("输入一个字符\n"); 21 scanf("%c",&ch); 22 getchar(); 23 24 printf("输入一个数字\n"); 25 scanf("%d",&a); 26 getchar(); 27 printf("ASKII=%d\n",ch); 28 29 printf("字符=%c\n",a); 30 } 31 32 return 0; 33 }
1 #if 0 2 8、输入一个字符,判断这个字符是0~9之间的数字,还是大写字母,还是小写字母。若都不是输出错误信息。 3 解题思路: 4 多分支条件判断: 5 #endif 6 7 #include<stdio.h> 8 9 int main(){ 10 char ch; 11 while(1){ 12 printf("输入要判定的字符:\n"); 13 scanf("%c",&ch); 14 getchar(); 15 if(ch>='a'&&ch<='z'){ 16 printf("%c是小写字母\n",ch); 17 }else if(ch>='A'&&ch<='Z'){ 18 printf("%c是大写字母\n",ch); 19 }else if(ch>='1'&&ch<='9'){ 20 printf("%c是数字\n",ch); 21 }else{ 22 printf("%c是特殊字符\n",ch); 23 } 24 } 25 return 0; 26 }
1 #if 0 2 9、计算输入时间的下一秒。例如输入12 15 32,输出12:15:33;输入21 59 59,输出22:00:00。 3 若输入非法时间(如输入小时是25、输入分钟/秒是61等情况)则报错。 4 5 解题思路: 6 一。多分支判断输入数据是否合法: 7 二。数据转换规则: 8 秒加一 9 如果秒加一大于59 10 则秒归零,分加一,此时如果分大于59 11 则分归零,时加一,此时如果时大于23 12 则时归零 13 14 错误分析: 15 一。数据转换不是多分支判断; 16 #endif 17 18 #include<stdio.h> 19 void print(int time){ 20 printf("%d:错误数值",time); 21 } 22 23 int main(){ 24 int hour,minute,second; 25 printf("输入时分秒 \n格式:xx xx xx\n"); 26 scanf("%d %d %d",&hour,&minute,&second); 27 28 29 //判断数据是否合法 30 if(0>hour||hour>23){ 31 print(hour); 32 return 0; 33 }else if(0>minute||minute>59){ 34 print(minute); 35 return 0; 36 }else if(0>second||second>59){ 37 print(second); 38 return 0; 39 } 40 41 42 if((++second)>59){ 43 second=0; 44 if((++minute)>59){ 45 minute=0; 46 if((++hour)>23){ 47 hour=0; 48 } 49 } 50 } 51 printf("\n当前时间:%d:%d:%d",hour,minute,second); 52 return 0; 53 }
1 //10、(课堂)练习:从键盘输入5个学生的成绩(整数),要求输出总成绩(整数)和平均成绩(小数) 2 #include<stdio.h> 3 4 int main(){ 5 6 int stu1,stu2,stu3,stu4,stu5; 7 int sum; 8 float ave; 9 printf("输入5个学生的成绩(整数):\n格式: xx xx xx xx xx\n"); 10 scanf("%d %d %d %d %d",&stu1,&stu2,&stu3,&stu4,&stu5); 11 sum=stu1+stu2+stu3+stu4+stu5; 12 ave=(float)sum/5; 13 printf("sum=%d,ave=%f",sum,ave); 14 return 0; 15 }
1 //11、(课堂)读以下程序,猜想输出的结果,再执行程序检验自己的猜想 2 #include <stdio.h> 3 int main(void) 4 { 5 double y; 6 float a = 2.0; 7 int b =6,c=3; 8 y = a*b/c-1.5+'A'; 9 printf("%f\n",y); 10 return 0; 11 }
1 //12、(课堂)读以下程序,猜想输出的结果,再执行程序检验自己的猜想 2 #include <stdio.h> 3 int main() 4 { 5 int i = 8,j = 10,k = 12; 6 int m,n,p; 7 8 m = ++i; 9 n = j--; 10 p = (++m)*(n++)+(--k); 11 printf("i=%d,j=%d,k=%d\n",i,j,k); 12 printf("m=%d,n=%d,p=%d\n",m,n,p); 13 return 0; 14 }
#if 0 13、(课堂)设 int a=3,b=4,c=5,d; 分别求出下列表达式的d的值(即判断此表达式真假) 1)d = a+b>c && b==c 2)d = a || b+c && b-c 3)d = !(a>b) && !c || 1 4)d = !(x=a)&&(y=b)&&0(x和y均为int型,求出x和y的值) 5)d = !(a+b)+c-1 && b+c/2 #endif
1 #if 0 2 14、(课堂)输入3个整数,从小到大输出 3 4 解题思路: 5 将所有的项遍历,两两对比所有项。 6 #endif 7 #include<stdio.h> 8 void jiao(int *a,int *b){ 9 (*a)^=(*b); 10 (*b)^=(*a); 11 (*a)^=(*b); 12 } 13 14 int main(){ 15 int a,b,c; 16 printf("输入3个整数:\n"); 17 scanf("%d %d %d",&a,&b,&c); 18 if(a>b){ 19 jiao(&a,&b); 20 } 21 if(a>c){ 22 jiao(&a,&c); 23 } 24 if(b>c){ 25 jiao(&b,&c); 26 } 27 printf("从小到大排序:%d %d %d",a,b,c); 28 return 0; 29 }
1 #if 0 2 15、(课堂)输入3个正整数作为3条线段的长度,判断这3条线段能否构成三角形。 3 构成三角形的条件是:任意两边之和大于第三边 4 5 解题思路: 6 对三边长度进行排序 7 找到三边中较短的两边,此两边之和大于第三边则可构成第三遍 8 #endif 9 #include<stdio.h> 10 void jiao(int *a,int *b){ 11 (*a)^=(*b); 12 (*b)^=(*a); 13 (*a)^=(*b); 14 } 15 16 int main(){ 17 int a,b,c; 18 printf("请输入三角形三边长度;\n"); 19 scanf("%d %d %d",&a,&b,&c); 20 if(a>b){ 21 jiao(&a,&b); 22 } 23 if(a>c){ 24 jiao(&a,&c); 25 } 26 if(b>c){ 27 jiao(&b,&c); 28 } 29 //printf("%d %d %d",a,b,c); 30 if((a+b)>c){ 31 printf("%d %d %d 可以构成三角形",a,b,c); 32 }else{ 33 printf("%d %d %d 不可以构成三角形",a,b,c); 34 } 35 return 0; 36 }
1 #if 0 2 16、(课堂)输入一个年份(正整数),判断这年是否是闰年。闰年判断标准:年份能被4整除;如若遇到100的倍数, 3 则需判断年份能否被400整除。(逢4一闰,逢百不闰,逢400又闰) 4 5 解题思路: 6 一。各个数据的包含关系: 7 能被4整除 包含 能被100整除 包含 能被400整除 8 二。多分支判断,从最小集合开始判断则判断条件最为简单; 9 10 #endif 11 #include<stdio.h> 12 13 int main(){ 14 int year; 15 printf("输入一个年份(正整数):\n"); 16 scanf("%d",&year); 17 18 if((year%400)==0){ 19 printf("%d是闰年",year); 20 }else if((year%100)==0){ 21 printf("%d不是闰年",year); 22 }else if((year%4)==0){ 23 printf("%d是闰年",year); 24 }else{ 25 printf("%d不是闰年",year); 26 } 27 return 0; 28 }
1 #if 0 2 17、(课堂)输入一个学生的成绩,输出该成绩对应的分数段。90~100为优,80~89为良,70~79为中,60~69为及格, 3 0~59为不及格,其他则输出错误信息。要求使用switch实现。 4 5 解题思路: 6 一。判断数据是否合法; 7 二。提取分数的十位进行switch判断。 8 9 #endif 10 #include<stdio.h> 11 int main(){ 12 int grade; 13 printf("输入一个学生的成绩;\n"); 14 scanf("%d",&grade); 15 if((grade>100)||(grade<0)){ 16 printf("%d数据不合法",grade); 17 return 1; 18 } 19 int aa=grade/10; 20 switch(aa){ 21 case 10: 22 case 9: 23 printf("%d等级为:优",grade); 24 break; 25 case 8: 26 printf("%d等级为:良",grade); 27 break; 28 case 7: 29 printf("%d等级为:中",grade); 30 break; 31 case 6: 32 printf("%d等级为:及格",grade); 33 break; 34 default: 35 printf("%d等级为:不及格",grade); 36 37 38 } 39 //printf("%lf",(grade*0.4)); 40 41 return 0; 42 }
1 #if 0 2 18、(课堂)运输公司对用户按路程计算费用。路程越远,每吨*千米运费折扣越高。计算运费公式如下: 3 freight = distance * distance * price * (1-discount); 4 路程与折扣的关系如下: 5 s<250:无折扣 6 250<=s<500:2%折扣 7 500<=s<1000:5%折扣 8 1000<=s<2000:8%折扣 9 2000<=s<3000:10%折扣 10 3000<=s:15%折扣 11 要求从键盘输入货运总重(单位吨)、货运路程(单位千米)、每吨*千米货运单价(单位元),输出总花费。 12 13 解题思路: 14 一。将重量进行分段,对每段重量的费用进行计算。 15 二。从大重量向小重量遍历计算比小重量向大重量计算各直观 16 例如 17 大到小:向算先算一千到一百,自减九百,再算一百到零, 18 小到大:先算零到一百,自减一百,再算零至900; 19 三。依次从大到小判断重量的大小,计算对应重量的费用,然后重量相应自减已计算重量。 20 21 #endif 22 23 24 25 #include<stdio.h> 26 int fun(int distance,int price,int weight){ 27 int freight=0; 28 if(distance>=3000){ 29 freight+=(distance-3000)*price*8.5*weight; 30 printf("\n%d=(%d-3000)*%d*0.9*%d\n",freight,distance,price,weight); 31 distance=3000; 32 33 } 34 if(distance>=2000){ 35 freight+=(distance-2000)*price*0.90*weight; 36 printf("\n%d=(%d-2000)*%d*0.9*%d\n",freight,distance,price,weight); 37 distance=2000; 38 39 } 40 if(distance>=1000){ 41 freight+=(distance-1000)*price*0.92*weight; 42 printf("\n%d=(%d-3000)*%d*0.9*%d\n",freight,distance,price,weight); 43 distance=1000; 44 45 } 46 if(distance>=500){ 47 freight+=(distance-500)*price*0.95*weight; 48 printf("\n%d=(%d-3000)*%d*0.9*%d\n",freight,distance,price,weight); 49 distance=500; 50 } 51 if(distance>=250){ 52 freight+=(distance-250)*price*0.95*weight; 53 printf("\n%d=(%d-250)*%d*0.9*%d\n",freight,distance,price,weight); 54 distance=250; 55 56 } 57 if(distance>=0){ 58 freight+=(distance)*price*weight; 59 printf("\n%d=(%d-3000)*%d*%d\n",freight,distance,price,weight); 60 } 61 if(distance<0){ 62 printf("\n%d路程不能为负",distance); 63 } 64 65 return freight; 66 } 67 68 int main(){ 69 int distance,price, weight; 70 int freight; 71 printf("输入 ;重量 单价 路程: "); 72 scanf("%d %d %d",&weight,&price,&distance); 73 //printf("%d %d %d",distance,unit,distance); 74 freight=fun(distance,price,weight); 75 printf("\n总价为:%d\n",freight); 76 77 return 0; 78 }
//19、(课堂)求1+2+3+……+99+100=?。使用while()、do-while()和for()三种循环分别实现。 //解题思路:for()和while互为语法糖,当循环超过一次是while()、do-while()等价; #include<stdio.h> int fun_while(int num){ int sum=0; int i=1; while(i<=num){ sum+=i; i++; } return sum; } int fun_dowhile(int num){ int sum=0; int i=1; do{ sum+=i; i++; }while(i<=num); return sum; } int fun_for(int num){ int sum=0; int i=1; for(i=1;i<=num;i++){ sum+=i; } return sum; } int main(){ int sum1,sum2,sum3; sum1=fun_while(100); sum2=fun_dowhile(100); sum3=fun_for(100); printf("while=%d ,dowhile=%d ,for=%d",sum1,sum2,sum3); return 0; }
1 #if 0 2 20、打印所有水仙花数。水仙花数是这样的三位数:各位数字的立方和等于其本身。如153就是一个水仙花数。 3 解题思路: 4 一。遍历100至999;每次分别提取个十百位上的数; 5 二。判断对每次提取的数进行立方和,对比和本身是否相等从而确定水仙花数。 6 7 #endif 8 9 #include<stdio.h> 10 void shuixian(){ 11 int i=100; 12 while(i<=999){ 13 14 int ge=i%10; 15 int bai=i/100; 16 int shi=(i/10)%10; 17 //printf("%d %d %d ",bai,shi,ge); 18 int sum=(ge*ge*ge)+(shi*shi*shi)+(bai*bai*bai); 19 //printf("\n水仙花数:%d\n",sum); 20 if(sum==i){ 21 printf("\n%d\n",sum); 22 } 23 i++; 24 } 25 26 } 27 28 29 int main(){ 30 shuixian(); 31 return 0; 32 }
1 #if 0 2 21、(课堂)打印斐波那契数列的前n项,其中n由键盘输入。斐波那契数列的特点如下: 3 F1=1 (n=1) 4 F2=1 (n=2) 5 Fn=Fn-1 + Fn-2 (n>=3) 6 7 解题思路: 8 一。应该建立一个数组来存储产生的斐波那契数列,但没有对数列的操作,所以不存储直接输出 9 二。使用两个标志位存储n-1 和n-2 的值,由此产生n的值。 10 #endif 11 12 #include<stdio.h> 13 14 void fei(int len){ 15 int one=1; 16 int two=1; 17 int i; 18 printf("%d\n%d \n",one,two); 19 for(i=3;i<=len;i++){ 20 int temp=two; 21 two+=one; 22 one=temp; 23 printf("%d\n",two); 24 } 25 } 26 int main(){ 27 int n; 28 printf("打印多少项"); 29 scanf("%d",&n); 30 31 fei(n); 32 33 return 0; 34 }
1 #if 0 2 22、(课堂)输出如下图形: 3 4*1 4 3***3 5 2*****5 6 1*******7 7 0*********9 8 ……5 9 其中需要输出几行由键盘输入。 10 11 解题思路: 12 一。确定输出多少行; 13 二。第i行的空格数:总行数-i 14 第i行的*数:i*2-1 15 #endif 16 #include<stdio.h> 17 18 void sanjiao(int len){ 19 //第I次输出几个* i*2-1 20 //第i次空几个 i-1 21 22 int kong,xiang,i; 23 for(i=1;i<=len;i++){ 24 //printf("%d",i); 25 //printf("%d",i); 26 27 for(kong=len-i;kong>=0;kong--){ 28 printf(" "); 29 } 30 for(xiang=(i*2-1);xiang>=1;xiang--){ 31 printf("*"); 32 33 } 34 printf("\n"); 35 } 36 37 38 39 } 40 41 int main(){ 42 int hang; 43 printf("输出几行三角"); 44 scanf("%d",&hang); 45 sanjiao(hang); 46 47 48 49 return 0; 50 }
1 #if 0 2 23、(课堂)现有100元钱要买以下3种文具。其中一个笔记本20元,一套尺6元,一个笔4元,每样文具至少买1个。 3 列举出所有的购买方案,以及列举出所有花光100元的购买方案 4 5 解题思路: 6 一。排除各买一件则剩余70元。 7 二。建立一个三重循环,分别代表笔记本,尺子,笔。可以遍历所有情况。总价恰好为70则为结果。 8 9 10 错误分析: 11 大O算法为n^3 ,算法效率太低。有待改进。 12 #endif 13 #include<stdio.h> 14 15 void wenju(int money){ 16 money-=(20+6+4);//30 70 17 int notebook,rule,pen; 18 for(notebook=0;notebook<=3;notebook++){ 19 for(rule=0;rule<=11;rule++){ 20 for(pen=0;pen<=17;pen++){ 21 if(notebook*20+rule*6+pen*4==70){ 22 if(notebook!=0){ 23 printf(" notebook=%d*20",notebook); 24 } 25 if(rule!=0){ 26 printf(" rule=%d*6",rule); 27 } 28 if(pen!=0){ 29 printf(" pen=%d*6",pen); 30 } 31 printf(" sum=70\n"); 32 } 33 } 34 } 35 } 36 } 37 38 int main(){ 39 //组合正好一百元; 40 wenju(100); 41 }
1 #if 0 2 24、(课堂)输出100~200间的所有素数 3 解题思路: 4 一。遍历100~200,每个数取余 2至n/2,判断如果所有余数都不为零则该数为素数。 5 #endif 6 #include<stdio.h> 7 8 void su(int low,int high){ 9 int i; 10 for(i=low;i<=high;i++){ 11 int j; 12 int st=0; 13 for(j=2;j<low;j++){ 14 if(i%j==0){ 15 st++; 16 } 17 18 } 19 if(st==0){ 20 printf("%d 是素数\n",i); 21 } 22 23 24 } 25 26 } 27 int main(){ 28 29 su(100,200); 30 return 0; 31 }
1 #if 0 2 25、计算1+2+3+……+99+100=?,在执行加法之前由用户输入3个数,这3个数不参与运算。例如输入3、57和89,则最终结果等于4901。 3 4 解题思路: 5 一。建立一个五个元素数组,中间三个用于用户输入,首尾元素分别为0 101。 6 二。依次遍历数组两两之间,元素值之间不包括本身进行累加, 7 三。将最后累加值总和进行输出为结果。 8 #endif 9 10 #include<stdio.h> 11 12 int Accumulate(int low,int high){ 13 int sum=0; 14 if((low+1)>=(high)){ 15 return 0; 16 } 17 for(++low;low<high;low++){ 18 sum+=low; 19 } 20 return sum; 21 } 22 23 int main(){ 24 int a[]={0,100,100,100,101}; 25 int i; 26 int sum=0; 27 printf("请输入三个数"); 28 scanf("%d %d %d",&a[1],&a[2],&a[3]); 29 for(i=1;i<5;i++){ 30 sum+=Accumulate(a[i-1],a[i]); 31 //sum+=Accumulate(0,101); 32 } 33 //sum=Accumulate(0,101); 34 printf("\n结果是:%d\n",sum); 35 36 return 0; 37 }
1 #if 0 2 26、编写一个程序,由键盘输入若干正整数,输入0代表输入完成。计算输入的数中的奇数的个数、总和、平均值; 3 计算输入的数中的偶数的个数、总和、平均值。 4 5 解题思路: 6 1。通过命令行传参获取数据,但数据是字符串形式 7 2。将字符串形式数据转换为int形式数据,放在一个数组中,便于操作 8 3。按要求对数据进行操作 9 10 #endif 11 12 13 #include<stdio.h> 14 #include<stdlib.h> 15 16 int my_even(int num[],int len){ 17 int even=0; 18 int i=0; 19 for(i=0;i<len;i++){ 20 if(num[i]%2==0){ 21 ++even; 22 } 23 24 } 25 26 27 return even; 28 } 29 int my_sum(int num[],int len){ 30 int sum=0; 31 int i=0; 32 for(i=0;i<len;i++){ 33 sum+=num[i]; 34 } 35 return sum; 36 } 37 38 int my_ave(int num[],int len){ 39 int ave=my_sum(num,len); 40 ave/=len; 41 return ave; 42 43 } 44 45 int main(int argc,char *argv[]){ 46 int i=0; 47 for(i=1;i<argc;i++){ 48 //printf("%s\n",argv[i]); 49 if(*argv[i]=='0'){ 50 //i; 51 break; 52 } 53 } 54 //printf("%s",argv[i]); 55 int *num; 56 int len=i-1; 57 if(NULL==(num=(int *)malloc(sizeof(int)*len))){ 58 perror("cannot malloc"); 59 return 1; 60 } 61 //num[0]=NULL; 62 63 for(i=0;i<len;i++){ 64 int sum=0; 65 char *s=argv[i+1]; 66 while(*s !='\0'){ 67 sum=sum*10+((*s++)-'0'); 68 //printf("%c",*s); 69 //++s; 70 } 71 num[i]=sum; 72 } 73 /* 74 for(i=0;i<len;i++){ 75 printf("%d \n",num[i]); 76 } 77 */ 78 int even=my_even(num,len); 79 int sum=my_sum(num,len); 80 int ave=my_ave(num,len); 81 printf("偶数个数:%d,总和:%d,平均值:%d。",even,sum,ave); 82 83 84 return 0; 85 }
1 #if 0 2 27、卡拉兹(Callatz)猜想: 3 对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去, 4 最后一定在某一步得到n=1 。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员, 5 拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证(3n+1),以至于有人说这是一个阴谋, 6 卡拉兹是在蓄意延缓美国数学界教学与科研的进展…… 7 我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过1000的正整数n,简单地数一下,需要多少步才能得到n=1? 8 解题思路: 9 1. 获取一个数 10 2. 判断是偶数则除二,是奇数乘三加一 11 3。 循环判断直至得到1; 12 13 #endif 14 15 #include<stdio.h> 16 17 int main(){ 18 int num=0; 19 printf("输入一个1000以内的自然数:"); 20 scanf("%d",&num); 21 22 while(num!=1){ 23 if(num%2==0){ 24 num/=2; 25 }else if(num%2==1){ 26 num=num*3+1; 27 } 28 printf("%d\t",num); 29 } 30 return 0; 31 }
1 //28、读懂以下程序,分析程序逻辑,画出流程图,说明程序的功能 2 #include<stdio.h> 3 int main() 4 { 5 int x,y; 6 printf("enter x:"); 7 scanf("%d",&x); 8 y=0; 9 if(x!=0) 10 { 11 if(x>0) 12 y=1; 13 else 14 y=-1; 15 } 16 printf("x=%d\ny=%d\n",x,y); 17 return 0; 18 }
1 #if 0 2 29、给定一个不多于5位的正整数,要求: 3 ①求出它是几位数 4 ②分别输出每一位数字(这里的位指十进制的位而非二进制的bit) 5 ③将数字逆序。例如输入123,则输出321 6 7 解题思路: 8 一。对输入数值合法性进行判定 9 二。判断数据的位数。 10 三。提取按从高位到低位进行,但将提取的数据按从低位到高位累加可得置逆结果。 11 12 错误分析: 13 本例中应该用一个数组存储提取的每一位的值。 14 #endif 15 16 #include<stdio.h> 17 #include<math.h> 18 19 int main(){ 20 int num; 21 int Q=10000; 22 int wei=0; 23 int ni=0; 24 printf("输入不大于十万(100000)的数"); 25 scanf("%d",&num); 26 if(num>99999){ 27 printf("数据过大"); 28 return 0; 29 } 30 while(num/Q==0){ 31 Q=Q/10; 32 33 } 34 while(Q>0){ 35 int a=num/Q; 36 Q=Q/10; 37 a=a%10; 38 39 printf("第%d位是:%d\n",wei+1,a); 40 ni=ni+pow(10,wei)*a; 41 wei++; 42 } 43 printf("\n置逆%d\n",ni); 44 45 46 47 48 return 0; 49 }
1 #if 0 2 30、使用公式求π的近似值 3 π/4 = 1 - 1/3 + 1/5 - 1/7 + …… 4 直到某一项的绝对值小于10^-6为止。 5 (提示:判断该数字是否小于10^-6,可以使用系统库函数fabs 6 fabs(f)>=1e-6//1e-6是10^-6的科学计数法表示方式 7 若要使用fabs()函数,则应包含头文件math.h 8 #include<math.h> 9 而且要在编译时添加-lm,即手动添加数学库libm.o 10 gcc qiupai.c -o qiupai -lm) 11 12 解题思路: 13 一。使用累加结束条件为某一项的绝对值小于10^-6为止。 14 二。每一项中加减交替,分子为1,分母为奇数递增。 15 三。累加结果乘四为π的值 16 17 错误经历: 18 将double型的数据以%d形式输出; 19 20 #endif 21 22 #include<stdio.h> 23 #include<math.h> 24 25 int main(){ 26 double PI; 27 double sum=1; 28 double item=0; 29 int i=1; 30 double jue=1; 31 //int fp=1; 32 while(fabs(jue)>=1e-6){ 33 if(i>0){ 34 i+=2; 35 }else{ 36 i-=2; 37 } 38 i=-i; 39 item=(double)1/i; 40 41 sum+=item; 42 //printf("item=%lf\n",sum); 43 44 jue=item; 45 if(jue<0){ 46 jue=-jue; 47 } 48 49 50 //fp++; 51 /* 52 if(fp>1000){ 53 break; 54 } 55 */ 56 57 } 58 PI=sum*4; 59 printf("π=%lf ",PI); 60 61 return 0; 62 }
1 //31、读懂以下程序,说明程序的功能 2 #include<stdio.h> 3 int main() 4 { 5 int m,n,r,m1,m2; 6 printf("请输入2个正整数:"); 7 scanf("%d%d",&m1,&m2); 8 m=m1; 9 n=m2; 10 do{ 11 r=m%n; 12 m=n; 13 n=r; 14 }while(r!=0); 15 printf("%d\n",m); 16 return 0; 17 }
1 #if 0 2 32、一个数如果恰好等于它的所有的因子之和,则这个数就称为“完数”。例如6的因子有1、2、3,而1+2+3=6,因此6是一个完数。 3 编程找出1000内所有的完数。 4 5 思路分级: 6 一。遍历2-1000内的所有数。 7 二。寻找每个数所有的公约数累加等于本身则为完数。 8 #endif 9 10 #include<stdio.h> 11 int main(){ 12 13 int num=0; 14 for(num=2;num<1000;num++){ 15 int sum=0; 16 int i=1; 17 for(i=1;i<=num/2;i++){ 18 if(num%i==0){ 19 20 sum+=i; 21 } 22 } 23 if(num==sum){ 24 printf("%d:是一个完数\n",sum); 25 } 26 } 27 28 29 return 0; 30 }
1 33、(课堂)思考这个宏定义错在哪里 2 #define S (r) PI*r*r//注意S与(r)之间有空格 3 4 5 34、我们在头文件(.h文件)中,经常看到这样的内容 6 #ifndef __H_INCLUDE__ 7 #define __H_INCLUDE__ 8 //头文件的实际内容 9 #endif 10 思考头文件的开头和结尾需要这样书写的原因。
1 35、(课堂)运行以下程序 2 int main() 3 { 4 char a,b; 5 a = getchar(); 6 b = getchar(); 7 putchar(a); 8 putchar(b); 9 return 0; 10 } 11 运行程序,输入x回车y回车,会发现输出的并不是xy,而是 12 x
1 #if 0 2 36、(课堂)使用数组存储斐波那契数列前40项,并输出 3 4 解题思路: 5 一。创建一个长度为40的数组。 6 二。将第一第二个元素置为1; 7 三。遍历数组 第N个元素的值为 元素(N-1)+元素(N-2); 8 #endif 9 10 #include<stdio.h> 11 #include<stdlib.h> 12 int *fibonacci(int len){ 13 int *p; 14 int i; 15 16 if(NULL==(p=(int *)malloc(sizeof(int)*len))){ 17 perror("cannot malloc"); 18 return NULL; 19 } 20 p[0]=1; 21 p[1]=1; 22 for(i=2;i<len;i++){ 23 p[i]=p[i-1]+p[i-2]; 24 25 } 26 return p; 27 } 28 void print(int p[],int len){ 29 int i; 30 for(i=0;i<len;i++){ 31 printf("p[%d]=%d\t",i+1,p[i]); 32 33 } 34 35 } 36 37 38 int main(){ 39 int *fib; 40 fib=fibonacci(40); 41 42 print(fib,40); 43 44 return 0; 45 }
1 #if 0 2 37、(课堂)从键盘输入10个学生的成绩,如果遇到大于100或者小于0的成绩需要提示输入错误重新输入。 3 之后计算10个学生的总成绩和平均成绩 4 5 解题思路: 6 一。创建长度为十的数组表示学生成绩 7 二。在输入时判断数值是否合法。 8 三。遍历数组累加 求总成绩和平均成绩 9 #endif 10 11 #include<stdio.h> 12 #include<stdlib.h> 13 14 int *getmemory(int len){ 15 int *p; 16 if(NULL==(p=(int *)malloc(sizeof(int)*len))){ 17 perror("cannot malloc"); 18 return NULL; 19 20 } 21 return p; 22 } 23 24 void my_scanf(int p[],int len){ 25 int i; 26 27 for(i=0;i<len;i++){ 28 printf("请输入第%d个学生成绩:\n",i+1); 29 //scanf("%d",&p[i]); 30 int grade=0; 31 scanf("%d",&grade); 32 if(grade<0||grade>100){ 33 printf("成绩区间为1至100"); 34 i--; 35 }else{ 36 p[i]=grade; 37 } 38 } 39 40 } 41 42 43 void my_printf(int p[],int len){ 44 int i; 45 46 for(i=0;i<len;i++){ 47 48 printf("第 %d个学生的成绩;%d",i+1,p[i]); 49 } 50 51 } 52 53 int my_sum(int p[],int len){ 54 int i=0; 55 int sum=0; 56 57 for(i=0;i<len;i++){ 58 sum+=p[i]; 59 60 } 61 return sum; 62 63 } 64 65 double my_ave(int p[],int len){ 66 double ave; 67 68 ave=my_sum(p,len)/len; 69 70 71 return ave; 72 73 } 74 75 int main(){ 76 int num; 77 int *stu; 78 79 printf("需要输入几个学生的成绩"); 80 scanf("%d",&num); 81 stu=getmemory(num);//创建容器 82 83 my_scanf(stu,num);//输入数据 84 85 //my_printf(stu,num);//输出数据 86 87 int sum=my_sum(stu,num);//求和 88 printf("学生的总成绩:%d",sum); 89 90 91 double ave=my_ave(stu,num);//求平均 92 printf("学生的平均成绩:%lf",ave); 93 94 return 0; 95 }
1 #if 0 2 38、(课堂)冒泡排序 3 从键盘输入10个各不相同的整数,存储在数组中,使用冒泡排序法将数组排序并输出 4 冒泡排序:是一种简单的排序算法 5 1)比较相邻的元素和其身后的元素。如果第一个比第二个大,就交换他们两个。 6 2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。一次循环过后,最后的元素应该会是最大的数。 7 3)针对所有的元素重复以上的步骤,除了最后一个。 8 4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 9 10 #endif 11 #include<stdio.h> 12 13 void my_scanf(int a[],int len){ 14 int i=0; 15 for(i=0;i<len;i++){ 16 17 printf("请输入第 %d个元素: ",i+1); 18 scanf("%d",&a[i]); 19 20 } 21 22 } 23 void bubblesort(int a[],int len){ 24 int i,j; 25 for(i=0;i<len-1;i++){ 26 27 for(j=0;j<len-1-i;j++){ 28 if(a[j]<a[j+1]){ 29 a[j]^=a[j+1]; 30 a[j+1]^=a[j]; 31 a[j]^=a[j+1]; 32 33 } 34 35 } 36 } 37 38 } 39 40 void my_printf(int a[],int len){ 41 int i=0; 42 for(i=0;i<len;i++){ 43 printf("a[%d]=%d\t",i+1,a[i]); 44 if(i%3==0)printf("\n"); 45 46 } 47 48 } 49 int main(){ 50 int a[10]={0}; 51 my_scanf(a,10); 52 53 bubblesort(a,10); 54 55 my_printf(a,10); 56 57 return 0; 58 }
1 #if 0 2 39、(课堂)自定义一个3*4的矩阵,输出矩阵中值最大的元素,并输入其数组下标 3 解题思路: 4 一。构建一个3*4的矩阵,然后给矩阵内的每个元素赋值。 5 二。创建三个变量分别存放最大值及其坐标 6 三。遍历矩阵得到最大值及其坐标 7 8 错误分析: 9 应该定义一个结构体来存放最大值及其坐标 10 #endif 11 #include<stdio.h> 12 #include<stdlib.h> 13 14 void my_scanf(int (*a),int x,int y){ 15 int i=0,j=0; 16 for(i=0;i<x;i++){ 17 for(j=0;j<y;j++){ 18 printf("请输入第 %d行%d 列的值:\n",i+1,j+1); 19 scanf("%d",&a[(i*(x+1)+j)]); 20 21 } 22 23 } 24 25 for(i=0;i<x;i++){ 26 for(j=0;j<y;j++){ 27 printf("a[%d][%d]=%d\t",i+1,j+1,a[(i*(x+1)+j)]); 28 //printf("%d\n",(i*(x+1)+j)); 29 30 } 31 32 } 33 34 } 35 36 37 38 39 void max(int (*a),int x,int y){ 40 int num,i=0,j=0,sub_i=1,sub_j=1; 41 num=a[0]; 42 for(i=0;i<x;i++){ 43 for(j=0;j<y;j++){ 44 if(num<a[(i*(x+1)+j)]){ 45 num=a[(i*(x+1)+j)]; 46 sub_i=i+1; 47 sub_j=j+1; 48 49 50 } 51 52 } 53 54 } 55 56 printf("\nmax:a[%d][%d]=%d",sub_i,sub_j,num); 57 58 } 59 60 61 62 int main(){ 63 //printf("哈哈哈999\n"); 64 int a[3][4]={0}; 65 //int (*a)=(int *)malloc(sizeof(int)*3*4); 66 67 //int i=3,j=4; 68 my_scanf(a,3,4); 69 70 max(a,3,4); 71 72 //free(a); 73 //a=NULL; 74 75 return 0; 76 }
1 #if 0 2 40、(课堂)打印杨辉三角型前10行 3 4 思路分析: 5 一。打印十行杨辉三角得第十行长度为十,所以建立一个长度为十的数组,作为每行的数据存储 6 二。按 0-9循环,代表行号,每次循环按行号递减遍历操作数组, 7 三。行号位元素置一,递减遍历 元素(n)=元素(n)+元素(n-1),首位不运算。 8 四。对一行操作完成可得到对应的杨慧三角值。输出。 9 10 错误分析: 11 没有将完整的杨慧三角记录。 12 #endif 13 14 #include<stdio.h> 15 #include<stdlib.h> 16 int main(){ 17 int row; 18 int *yang=NULL; 19 int i=0; 20 21 printf("打印几行杨辉三角:\n"); 22 scanf("%d",&row); 23 yang=(int *)malloc(sizeof(int)*row); 24 if(NULL==yang){ 25 perror("cannot malloc"); 26 return 1; 27 } 28 for(i=0;i<row;i++){ 29 yang[i]=1; 30 int j; 31 for(j=i-1;j>0;j--){ 32 yang[j]+=yang[j-1]; 33 //printf("4444444444"); 34 } 35 int k=0; 36 for(k=0;k<=i;k++){ 37 printf("%d\t",yang[k]); 38 } 39 printf("\n"); 40 41 } 42 43 44 return 0; 45 }
1 #if 0 2 41、给定任一个各位数字不完全相同的4位正整数,如果我们先把4个数字按非递增排序,再按非递减排序,然后用第1个数字减第2个数字, 3 将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的6174,这个神奇的数字也叫Kaprekar常数。 4 例如,我们从6767开始,将得到 5 7766 - 6677 = 1089 6 9810 - 0189 = 9621 7 9621 - 1269 = 8352 8 8532 - 2358 = 6174 9 7641 - 1467 = 6174 10 ... ... 11 现给定任意4位正整数,请编写程序演示到达黑洞的过程。 12 13 思路分析: 14 一。利用循环结束条件为结果等于6174 15 二。接收数据, 16 三。对数据排序,得到递增递减两数的差值,判断是否为6174,否则继续循环。 17 #endif 18 #include<stdio.h> 19 void bubblesort(int a[],int len){ 20 int i,j; 21 for(i=0;i<len-1;i++){ 22 for(j=0;j<len-1-i;j++){ 23 if(a[j]>a[j+1]){ 24 a[j]^=a[j+1]; 25 a[j+1]^=a[j]; 26 a[j]^=a[j+1]; 27 } 28 } 29 } 30 31 } 32 33 int dijian(int danwei[],int len){ 34 int sum=0; 35 bubblesort(danwei,len); 36 int i=0; 37 for(i=len-1;i>=0;i--){ 38 sum=sum*10; 39 sum+=danwei[i]; 40 } 41 return sum; 42 } 43 int dizeng(int danwei[],int len){ 44 int sum=0; 45 bubblesort(danwei,len); 46 int i=0; 47 for(i=0;i<len;i++){ 48 sum=sum*10; 49 sum+=danwei[i]; 50 } 51 return sum; 52 } 53 54 int main(){ 55 56 //获得一个数 57 int num=0; 58 printf("请输入一个四位数:"); 59 scanf("%d",&num); 60 while(num!=6174){ 61 //分解数值 62 63 int danwei[4]; 64 danwei[3]=num/1000; 65 danwei[2]=(num%1000)/100; 66 danwei[1]=(num%100)/10; 67 danwei[0]=num%10; 68 //排序成两个新数据 69 int jian=dijian(danwei,4); 70 int zeng=dizeng(danwei,4); 71 //相减得到新数据 72 num=jian-zeng; 73 printf("%d-%d=%d\n",jian,zeng,num); 74 75 } 76 return 0; 77 }
2 42、(课堂)自定义2个字符数组,不使用系统提供的strcat()函数,实现strcat()函数功能。 3 43、(课堂)自定义2个字符数组,不使用系统提供的strcpy()函数,实现strcpy()函数功能。 4 44、(课堂)自定义2个字符数组,不使用系统提供的strcmp()函数,实现strcmp()函数功能。 5 45、(课堂)自定义1个字符数组,不使用系统提供的strlen()函数,实现strlen()函数功能。
1 #if 0 2 46、输出以下图案。要求每行的字符数与每次偏移几个字符由用户输入。结束条件为最后一行开头与第一行末尾对齐或在其之后 3 ********** 4 ********** 5 ********** 6 ********** 7 ********** 8 ********** 9 10 思路分析: 11 一。空格数=++kong * 偏移量 12 二。循环执行条件 空格数小于字符数 13 14 15 #endif 16 17 #include<stdio.h> 18 19 int main(){ 20 int zifu,pianyi; 21 printf("每行的字符数"); 22 scanf("%d",&zifu); 23 printf("每次偏移几个字符"); 24 scanf("%d",&pianyi); 25 int kongge=0; 26 int kong=0; 27 while(kongge<zifu){ 28 int k=0; 29 kongge=kong*pianyi; 30 for(k=0;k<kongge;k++){ 31 printf(" "); 32 } 33 kong++; 34 35 int j=0; 36 for(j=0;j<zifu;j++){ 37 printf("*"); 38 } 39 printf("\n"); 40 41 42 } 43 return 0; 44 }
1 #if 0 2 47、按以下规律加密一段文字。 3 A->Z a->z 4 B->Y b->y 5 C->X c->x 6 …… 7 Z->A z->a 8 其中不是字母的部分不加密。 9 10 解题思路: 11 一。利用字母对应的ASCII码表的数值进行运算,达到加密的目的。 12 二。B-A=Z-Y; C-A=Z-X ==》X=Z-(C-A)=Z-C+A 13 14 #endif 15 16 17 #include<stdio.h> 18 19 int main(){ 20 int i=0; 21 char encryption[14]={'0','A','a','0','B','b','0','Z','z','0','0','Q','q','0'}; 22 for(i=0;i<14;i++){ 23 printf("%c",encryption[i]); 24 } 25 printf("\n加密结果:\n"); 26 for(i=0;i<14;i++){ 27 if((encryption[i]>='A')&&(encryption[i]<='Z')){ 28 encryption[i]='Z'-encryption[i]+'A'; 29 } 30 if((encryption[i]>='a')&&(encryption[i]<='z')){ 31 encryption[i]='z'-encryption[i]+'a'; 32 } 33 34 } 35 for(i=0;i<14;i++){ 36 printf("%c",encryption[i]); 37 } 38 return 0; 39 }
1 #if 0 2 48、规定一句话中以空格作为分词符。输入一句话,求一句话中最长单词的长度。例如: 3 I love China! 4 则最长单词是China!,最长单词长度是6 5 6 解题思路: 7 一。因为不需要对数组本身进行修改,所以直接操作字符串常量 8 二。四个变量, 9 最高值 最高值单词首地址 10 每个单词的长度 单词首地址 11 三。输出最高值的结果。 12 13 错误分析: 14 如果以空格为判断标志则最后一个单词无法判断 15 解决在循环结束后再判断一次; 16 17 18 如果要用scanf()输入需要知道语句长度 19 scanf("%s",p);这样写并不是在代码区p的值使stdin的地址; 20 21 #endif 22 23 #include<stdio.h> 24 25 void my_printf(char p[]){ 26 while((*p!='\0'&&(*p!=' '))){ 27 printf("%c",*p++); 28 } 29 } 30 31 int main(){ 32 char *p="I love China!"; 33 int max=0; 34 int len=0; 35 36 char *plen=p; 37 38 //scanf("%s",p);||(*p!=' ') 39 40 printf("%s\n",p); 41 42 char *pmax=p; 43 while(*p!='\0'){ 44 if(*p!=' '){ 45 ++len; 46 47 }else{ 48 49 if(len>max){ 50 max=len; 51 pmax=plen; 52 53 } 54 plen=p+1; 55 len=0; 56 } 57 58 p++; 59 } 60 if(len>max){ 61 max=len; 62 pmax=plen; 63 } 64 printf("最大长度:%d,单词:",max); 65 my_printf(pmax); 66 67 //printf("最大长度:%s\n",pmax); 68 69 70 //printf("最大长度:%p\n",plen); 71 //printf("最大长度:%p\n",p); 72 73 74 return 0; 75 }
1 //49、读以下程序,猜想程序的运行结果,然后上机验证 2 #include<stdio.h> 3 int main() 4 { 5 int i; 6 int lh,rh,le,re,m; 7 char *lefthand[] = {"╮","o","<","~\\"}; 8 char *righthand[]= {"╭","o",">","/~"}; 9 char *lefteye[] = {"╯","^","-","=",">","@","⊙"}; 10 char *righteye[]= {"╰","^","-","=","<","@","⊙"}; 11 char *mouth[] = {"Д","▽","_","ε","^"}; 12 printf("请选择左手:\n"); 13 for(i=0;i<=3;i++) 14 { 15 printf("%d.[%s] ",i+1,lefthand[i]); 16 } 17 printf("\n"); 18 scanf("%d",&lh); 19 lh--; 20 printf("请选择右手:\n"); 21 printf("推荐:%d.[%s]\n其他:",lh+1,righthand[lh]); 22 for(i=0;i<=3;i++) 23 { 24 if(i==lh) 25 continue; 26 printf("%d.[%s] ",i+1,righthand[i]); 27 } 28 printf("\n"); 29 scanf("%d",&rh); 30 rh--; 31 printf("请选择左眼:\n"); 32 for(i=0;i<=6;i++) 33 { 34 printf("%d.[%s] ",i+1,lefteye[i]); 35 } 36 printf("\n"); 37 scanf("%d",&le); 38 le--; 39 printf("请选择右眼:\n"); 40 printf("推荐:%d.[%s]\n其他:",le+1,righteye[le]); 41 for(i=0;i<=6;i++) 42 { 43 if(i==le) 44 continue; 45 printf("%d.[%s] ",i+1,righteye[i]); 46 } 47 printf("\n"); 48 scanf("%d",&re); 49 re--; 50 printf("请选择嘴:\n"); 51 for(i=0;i<=4;i++) 52 { 53 printf("%d.[%s] ",i+1,mouth[i]); 54 } 55 printf("\n"); 56 scanf("%d",&m); 57 m--; 58 printf("%s(%s%s%s)%s\n",lefthand[lh],lefteye[le],mouth[m],righteye[re],righthand[rh]); 59 return 0; 60 }
#if 0 50、围绕着山顶有10个圆形排列的洞,狐狸要吃兔子,兔子说:“可以,但必须先找到我,我就藏身于这十个洞中的某个洞。 你从1号洞找,下次隔1个洞(即3号洞)找,第三次隔2个洞(即6号洞)找,再隔3个…以后在这个圆圈中如此类推,次数不限。 ”但狐狸从早到晚进进出出了1000次,仍没有找到兔子。 问:兔子可能藏身于哪(几)个洞中? 思路分析: 一。创建一个十一个元素数组,元素角标对应山洞。 二。 第几次寻找 对应的洞号 相应洞号的差值 1 1 1 2 3 2 3 6 3 三。根据洞号差来确定每次的洞号,山洞对应的元素自增; 四。输出每个元素的值为零即使没有找过的。 #endif #include<stdio.h> int main(){ int i=1; int sum=0; int fp[11]={0}; int j; for(i=1;i<=1000;i++){ sum+=i; j=sum%10; //if(j==0)j=10; fp[j]++; } fp[10]=fp[0]; int k=1; for(k=1;k<11;k++){ printf("%d号洞被找%d次\n",k,fp[k]); } return 0; }
提高题 提高题 提高题 提高题 提高题
1 #if 0 2 1、编写程序,随机生成一个1~10内的数,让对方猜3次。如果3次内能猜中则输出“恭喜你”;若3次内猜不中则输出正确答案。 3 C语言中提供生成随机数的函数rand() 4 用法: 5 ①所需头文件: 6 7 ②生成随机数种子: 8 #include<math.h> 9 #include<time.h> 10 //sleep(1); 11 srand(time(0)); 12 13 14 ③生成某范围内的随机数。例如生成1~100内的随机数 15 #include<stdlib.h> 16 int a = rand()%100+1;//将这个数取余100,会得到一个0~99之间的数,将这个数+1即可得到1~100之间的数 17 18 解题思路: 19 一。生成随机数 20 二。三次循环判断,每次循环进行判等, 21 22 错误分析: 23 第一个方法问题: 24 1 1 1 1 1 1 25 5 5 5 5 5 5 26 7 7 7 7 7 7 27 第二个方法问题: 28 1 5 7 3 6 4 29 1 5 7 3 6 4 30 1 5 7 3 6 4 31 32 #include<stdlib.h> 33 #include<time.h> 34 #include<math.h> 35 头文件互相冲突不能共存; 36 37 #endif 38 39 #include<stdio.h> 40 #include<stdlib.h> 41 #include<time.h> 42 43 44 int main(){ 45 /* 46 int a ; 47 while(a!=3){ 48 a = rand()%10+1; 49 printf("%d\t",a); 50 } 51 52 53 54 55 56 int a ; 57 int i=0; 58 while(i!=3){ 59 a = srand(time(0))%10+1; 60 printf("!!!!!!!!!!%d\t",a); 61 i++; 62 } 63 64 */ 65 66 int i; 67 srand((unsigned)(time(NULL))); 68 int a=rand()%10+1; 69 for(i=0;i<3;i++){ 70 int b; 71 printf("\n输入猜测值[1-10]: "); 72 scanf("%d",&b); 73 if(a==b){ 74 printf("888恭喜你!"); 75 return 0; 76 } 77 } 78 79 printf("%d是正确答案: ",a); 80 81 82 return 0; 83 }
1 #if 0 2 2、在上一题基础上,编写一个彩票程序。 3 彩票程序在后台随机生成1~35内的7个各不相同的数字。用户会输入一组7个数字,中奖规则: 4 猜中 5 7个500万 6 6个100万 7 5个1万 8 4个5000 9 3个500 10 0,1,2个没中奖 11 输出是否中奖及奖金。 12 13 解题思路: 14 如何高效的生成随机数; 15 #endif 16 17 #include<stdio.h> 18 #include<stdlib.h> 19 #include<time.h> 20 int main(){ 21 int caipiao[7]; 22 srand((unsigned)(time(NULL))); 23 int i; 24 for(i=0;i<7;i++){ 25 int j=0; 26 int temp=rand()%35+1; 27 for(j=0;j<i;j++){ 28 if(caipiao[i]==temp){ 29 i--; 30 continue; 31 } 32 } 33 caipiao[i]=temp; 34 } 35 int my_cai[7]; 36 printf("请输入竞猜彩票七位1-35的数:例 1 2 3 4 5 6 7 \n"); 37 scanf("%d %d %d %d %d %d %d",&my_cai[0],&my_cai[1],&my_cai[2],&my_cai[3],&my_cai[4],&my_cai[5],&my_cai[6]); 38 int k=0; 39 for(i=0;i<7;i++){ 40 int j; 41 for(j=0;j<7;j++){ 42 if(my_cai[i]==caipiao[j]) 43 k++; 44 } 45 } 46 printf("您的竞猜结果:"); 47 if(k==7){ 48 printf("500万"); 49 }else if(k==6){ 50 printf("100万"); 51 }else if(k==5){ 52 printf("1万"); 53 }else if(k==4){ 54 printf("5000"); 55 }else if(k==3){ 56 printf("500"); 57 }else{ 58 printf("抱歉"); 59 } 60 printf("猜对%d个\n",k); 61 for(i=0;i<7;i++){ 62 printf("第%d位号码:%d 。我的竞猜%d \n",i+1,caipiao[i],my_cai[i]); 63 } 64 return 0; 65 }
1 #if 0 2 3、判断一个矩阵中是否存在鞍点,若存在输出鞍点。鞍点是这样一个数字:在该行最大,在该列最小。例如: 3 1 2 6 4 4 5 6 7 8 5 9 10 11 12 6 则数字6(a[0][2])是鞍点。一个矩阵可能没有鞍点,可能拥有不止一个鞍点。 7 8 解题思路: 9 一。 寻找每行的最大值 10 二。判断最大值是否为所在列的最小值 11 12 #endif 13 14 #include<stdio.h> 15 16 int main(){ 17 typedef struct an{ 18 int max; 19 int i; 20 int j; 21 }an; 22 23 24 int a[3][4]={ 25 {1 ,2 ,6 , 4}, 26 {5 , 6 ,7 ,8}, 27 {9 ,10 ,11 ,12} 28 }; 29 30 int hang=3,lie=4; 31 int i=0; 32 an andian; 33 34 //遍历所有行 35 for(i=0;i<hang;i++){ 36 andian.max=a[i][0]; 37 andian.i=i; 38 andian.j=0; 39 40 int j; 41 //寻找这行里最大值 42 for(j=1;j<lie;j++){ 43 if(andian.max==a[i][j]){ 44 break; 45 } 46 if(andian.max<a[i][j]){ 47 andian.max=a[i][j]; 48 //andian.i=i; 49 andian.j=j; 50 51 52 53 } 54 //遍历完行最后一位且行中没有相等 取得行最大值; 55 if(j==(lie-1)){ 56 //遍历行最大值所在列,判断是否为最小值 57 int ii,jj=(andian.j); 58 for(ii=0;ii<hang;ii++){ 59 if(ii==i)continue; 60 if(a[ii][jj]<andian.max){ 61 break; 62 } 63 if(ii==hang-1){ 64 printf("鞍点=%d ,行=%d 列=%d\n",andian.max,andian.i+1,andian.j+1); 65 } 66 } 67 68 69 } 70 71 } 72 73 } 74 75 76 return 0; 77 }
1 #if 0 2 4、使用1、2、3、4四个数字能组成多少个无重复数字的三位数?输出这些三位数。 3 4 思路分析: 5 达成遍历的效果。 6 7 错误分析: 8 大o算法=n^3 ,比较高; 9 10 #endif 11 #include<stdio.h> 12 13 int main(){ 14 int a[4]={1,2,3,4}; 15 int i,j,k,len=4; 16 for(i=0;i<len;i++){ 17 18 for(j=0;j<len;j++){ 19 if(i==j)continue; 20 for(k=0;k<len;k++){ 21 if((i==k)||(j==k))continue; 22 printf("%d \t",(a[i]*10+a[j])*10+a[k]); 23 } 24 } 25 } 26 27 28 29 return 0; 30 }
1 #if 0 2 5、输入一个日期(年、月、日),计算该日期是这一年的第几天。注意判断闰年 3 解题思路: 4 一。建立一个数组存贮每个月的天数 5 二。判断是否为闰年,若月份大于2则天数加一。 6 7 错误分析: 8 没有输入数据合法性分析。 9 认为最好的方法是创建两个月的数组,一个存储闰年。 10 #endif 11 12 #include<stdio.h> 13 int runnian(int year){ 14 15 if((year%400)==0){ 16 printf("%d是闰年\n",year);return 1; 17 }else if((year%100)==0){ 18 printf("%d不是闰年\n",year);return 0; 19 }else if((year%4)==0){ 20 printf("%d是闰年\n",year);return 1; 21 }else{ 22 printf("%d不是闰年\n",year);return 0; 23 } 24 return 0; 25 } 26 27 int main(){ 28 int yueping[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 29 int nian,yue,ri; 30 printf("输入年 月 日:"); 31 scanf("%d %d %d",&nian,&yue,&ri); 32 if(runnian(nian)&&(yue>2)){ 33 ri++; 34 } 35 int sum=0; 36 int i; 37 for(i=1;i<yue;i++){ 38 sum+=yueping[i]; 39 } 40 sum+=ri; 41 printf("%d:%d:%d一共有:%d 天。",nian,yue,ri,sum); 42 43 44 45 return 0; 46 }
1 #if 0 2 6、输出9*9乘法口诀表 3 1*1=1 4 1*2=2 2*2=4 5 1*3=3 2*3=6 3*3=9 6 …… 7 8 思路分析: 9 1 *1 10 2 *1 2 11 3 *1 2 3 12 4 *1 2 3 4 13 5 *1 2 3 4 5 14 15 利用一个双重循环产生上图数据 16 #endif 17 18 #include<stdio.h> 19 20 int main(){ 21 int len=9; 22 int i=1; 23 for(i=1;i<=len;i++){ 24 int j=1; 25 for(j=1;j<=i;j++){ 26 printf("%d*%d=%d\t",i,j,(i*j)); 27 } 28 printf("\n"); 29 30 } 31 32 33 return 0; 34 }
1 #if 0 2 7、输入2个正整数,求它们的最大公约数和最小公倍数 3 解题思路: 4 最大公约数: 5 n--, 第一个取余为零的数 6 n++,第一个取余为零的数 7 #endif 8 9 #include<stdio.h> 10 11 int main(){ 12 13 int a,b,mix,max,yueshu,beishu; 14 printf("输入两个数:\n"); 15 scanf("%d %d",&a,&b); 16 mix=a<b?a:b; 17 max=a>b?a:b; 18 19 int i=0; 20 //求最大公约数 21 for(i=mix;i>0;i--){ 22 if((mix%i==0)&&(max%i==0)){ 23 yueshu=i; 24 break; 25 } 26 } 27 //求公倍数 28 for(i=max;i<=max*mix;i++){ 29 if((i%mix==0)&&(i%max==0)){ 30 beishu=i; 31 break; 32 } 33 } 34 printf("%d,%d的公约数%d;公倍数%d",mix,max,yueshu,beishu); 35 36 37 }
#if 0 8、楼梯有n阶台阶,上楼可以一步上1阶,也可以一步上2阶,编程序计算n阶台阶共有多少种不同的走法 解题思路: 一。全部是一阶 二。有一个二阶 三。有两个二阶 四。以此类推到二阶最多的情况。 五。对每种情况进行全排序 111.....1111 2..2 将2插入1看有多少情况 2插到2旁边是一样的。 #endif #include<stdio.h> int main(){ int taijie; printf("输入台阶数:\n"); scanf("%d",&taijie); int liangjie=0,sum=0; while((taijie-2*liangjie)>=0){ int yijie=taijie-2*liangjie; int zoufa=1; //i等于2阶的个数,代表插入几次; int i=liangjie; while(i){ zoufa*=(yijie+1); i--; } printf("有%d步为两阶,走法%d种\n",liangjie,zoufa); sum+=zoufa; ++liangjie; } printf("\n总共有%d种\n",sum); return 0; }
1 #if 0 2 9、协助破案。假设已经查清,有a、b、c、d、e五个犯罪嫌疑人可能参与作案,但是不知道哪(几)个是真正的案犯。不过有证据表明: 3 4 ⒈如果a参与了作案,则b一定也参与 5 ⒉b和c两人中只有一人参与了作案 6 ⒊c和d要么都参与作案,要么都没有参与 7 ⒋d和e两个人中至少有一人参与了作案 8 ⒌如果e作案,则a和d必定协助作案。 9 编程找出谁是真正的案犯(可能不止一人) 10 11 解题思路: 12 设计五个变量abcde; 13 如果abcde全部被判定,赋值则跳出循环。 14 15 如果D=1;可以实现对a到e的判断;则值出现一次循环未改变 跳出循环 16 否则e=1;再次循环 17 18 错误分析: 19 应该是我输入一个猜测,然后输出此猜测的结果。 20 根据题意有两种可能。 21 #endif 22 23 #include<stdio.h> 24 25 int main(){ 26 int a=7,b=7,c=7,d=7,e=7; 27 //判断有没有语句执行 28 int aa,bb,cc,dd,ee; 29 //假设d=1;看是不是能判断所有人,若果i=0时还不能判断所有人。在循环中改成c=1 30 d=1; 31 while(a==7||b==7||c==7||d==7||e==7){ 32 aa=a;bb=b;cc=c;dd=d;ee=e; 33 //⒈如果a参与了作案,则b一定也参与 34 if(a==1){ 35 b=1; 36 37 } 38 //⒉b和c两人中只有一人参与了作案 39 if(b==0){ 40 c=1; 41 42 }else { 43 c=0; 44 } 45 if(c==0){ 46 b=1; 47 }else{ 48 b=0; 49 } 50 51 //⒊c和d要么都参与作案,要么都没有参与 52 if(c==0){ 53 d=0; 54 55 }else if(d==0){ 56 c=0; 57 58 } 59 //⒌如果e作案,则a和d必定协助作案。 60 if(e==1){ 61 a=1; 62 d=1; 63 64 } 65 printf("a=%d,b=%d,c=%d,d=%d,e=%d\n",a,b,c,d,e); 66 67 //⒋d和e两个人中至少有一人参与了作案 68 if(a==aa && b==bb && c==cc && d==dd&& e==ee){ 69 a=7;b=7;c=7;d=7;e=1; 70 } 71 72 73 } 74 printf("最终结果a=%d,b=%d,c=%d,d=%d,e=%d\n\n\n",a,b,c,d,e); 75 if(a==1){ 76 printf("a是罪犯\n"); 77 }else{ 78 printf("a不是罪犯\n"); 79 } 80 if(b==1){ 81 printf("b是罪犯\n"); 82 }else{ 83 printf("b不是罪犯\n"); 84 } 85 if(c==1){ 86 printf("c是罪犯\n"); 87 }else{ 88 printf("c不是罪犯\n"); 89 } 90 if(d==1){ 91 printf("d是罪犯\n"); 92 }else{ 93 printf("d不是罪犯\n"); 94 } 95 if(e==1){ 96 printf("e是罪犯\n"); 97 }else{ 98 printf("e不是罪犯\n"); 99 } 100 101 102 return 0; 103 }
1 #if 0 2 10、给定一个5位数,判断这个数字是否是回文数。例如12321是回文数,而12345就不是回文数。 3 解题思路: 4 因为是给定的五位数 5 可以将第一位和第五位比,第二位和第四位比。 6 #endif 7 8 #include<stdio.h> 9 10 int huiwen(int num){ 11 if((num/10000)!=(num%10)){ 12 return 0; 13 } 14 if((num/1000%10)!=(num%100/10)){ 15 return 0; 16 } 17 return 1; 18 } 19 20 int main(){ 21 printf("请输入一个五位数"); 22 int num; 23 scanf("%d",&num); 24 int i=huiwen(num); 25 if(i){ 26 printf("%d是回文数",num); 27 }else{ 28 printf("%d不是回文数",num); 29 } 30 31 32 return 0; 33 }
1 #if 0 2 11、自定义一个5*5矩阵,将这个矩阵转置。 3 一。定义一个5*5 的矩阵A; 4 二。新建一个5*5 的矩阵B; 5 B[i][j]=a[j][i]; 6 7 8 #endif 9 10 #include<stdio.h> 11 12 void my_scanf(int *a,int x,int y){ 13 int i=0,j=0; 14 for(i=0;i<x;i++){ 15 //j不应该从零开始 16 for(j=0;j<y;j++){ 17 printf("请输入第 %d行%d 列的值:\n",i+1,j+1); 18 scanf("%d",&a[(i*(x+1)+j)]); 19 20 } 21 22 } 23 24 for(i=0;i<x;i++){ 25 for(j=0;j<y;j++){ 26 printf("a[%d][%d]=%d\t",i+1,j+1,a[(i*(x+1)+j)]); 27 //printf("%d\n",(i*(x+1)+j)); 28 29 } 30 31 } 32 //printf(""\n\n\n); 33 34 } 35 void zhuanzhi(int *b,int x,int y,int *a ){ 36 int i=0,j=0; 37 for(i=0;i<x;i++){ 38 //j不应该从零开始 39 for(j=0;j<y;j++){ 40 //printf("请输入第 %d行%d 列的值:\n",i+1,j+1); 41 //scanf("%d",&a[(i*(x+1)+j)]); 42 b[(i*(x+1)+j)]=a[(j*(x+1)+i)]; 43 } 44 45 } 46 for(i=0;i<x;i++){ 47 for(j=0;j<y;j++){ 48 printf("b[%d][%d]=%d\t",i+1,j+1,b[(i*(x+1)+j)]); 49 //printf("%d\n",(i*(x+1)+j)); 50 51 } 52 53 } 54 } 55 56 int main(){ 57 printf("创建矩阵A;\n"); 58 int a[5][5]={0}; 59 my_scanf(a,5,5); 60 printf("创建转置矩阵B: \n"); 61 int b[5][5]={0}; 62 zhuanzhi(b,5,5,a); 63 64 65 return 0; 66 }
1 #if 0 2 13、假设你收到了一行使用凯撒密码加密过的单词但不知道秘钥(偏移字母数),请破译这段密文。 3 密文:PELCGBTENCUL 4 提示:凯撒密码加密是一种字母替换加密算法,其加密原则是:将26个字母连接成环,明文的所有字母被后n位的字母替换得到密文。例如当n=3的时候替换规则是: 5 A--->D 6 B--->E 7 C--->F 8 …… 9 X--->A 10 Y--->B 11 Z--->C 12 明文HELLO----->密文KHOOR 13 14 解题思路: 15 一。输入一段密码和原文判断秘钥 16 二。根据秘钥解码密文 17 18 #endif 19 20 #include<stdio.h> 21 #define len 20 22 23 void jiemi(char *kaisa,char *kaisayuanwen,int miyao){ 24 25 while(*kaisa!='\0'){ 26 *kaisayuanwen=*kaisa+miyao; 27 28 *kaisa++; 29 *kaisayuanwen++; 30 } 31 *kaisayuanwen='\0'; 32 33 } 34 int main(){ 35 char mingwen[len],miwen[len],kaisa[len],kaisayuanwen[len]; 36 printf("输入明文:\n"); 37 scanf("%s",mingwen); 38 39 printf("输入密文:\n"); 40 scanf("%s",miwen); 41 42 int miyao=mingwen[0]-miwen[0]; 43 44 printf("输入凯撒密文\n"); 45 scanf("%s",kaisa); 46 47 48 jiemi(kaisa,kaisayuanwen,miyao); 49 printf("输入凯撒原文\n"); 50 51 printf("%s\n",kaisayuanwen); 52 53 54 return 0; 55 }
1 #if 0 2 14、棋子移动问题 3 有2n(n>=4)个棋子排成一行,其中黑棋B有n个,白棋W有n个,并留有两个空格。 4 例如,当n=4时排列如下所示:(W为白棋,B为黑棋,0为空格) 5 W W W W B B B B 0 0 6 当n=5时排列如下所示:(W为白棋,B为黑棋,0为空格) 7 W W W W W B B B B B 0 0 8 现在需要移动棋子,移动规则如下: 9 ⒈每次必须同时移动相邻的两个棋子 10 ⒉每次移动必须跳过若干棋子 11 ⒊不能随意调换任意两个棋子的位置 12 目标:将所有的棋子移动为黑白棋相间的形式,中间不能有空格。 13 例如:当n=4时移动步骤如下: 14 起始: W W W W B B B B 0 0 15 第一步:W W W 0 0 B B B W B 16 第二步:W W W B W B B 0 0 B 17 第三步:W 0 0 B W B B W W B 18 第四步:W B W B W B 0 0 W B 19 第五步:0 0 W B W B W B W B(完成) 20 编程实现:从键盘输入n(n>=4),求每一步的棋子移动 21 22 思路分析: 23 一。创建一个数组, n-1赋值W n-1赋值B 最后两个赋值'0'; 24 二。调换原则: 25 4 26 0 1 2 3 4 5 6 7 8 9 27 起始: W W W W B B B B 0 0 28 29 第一步:W W W 0 0 B B B W B //2n <==>n-1 /2-1 -2/1 30 31 第二步:W W W B W B B 0 0 B n-1 <==>2n-1 *2+1 32 33 第三步:W 0 0 B W B B W W B 2n-1 <==>n-3 /2 34 35 第四步:W B W B W B 0 0 W B n-3 <==> 2n-2 36 37 第五步:0 0 W B W B W B W B(完成) 2n-2<==>n-4 38 39 结束条件: 40 n-4=0 41 42 43 三。采用递归的方法 44 递归逻辑:N>4, 45 递归出口:N<4, 46 47 48 #endif 49 50 #include<stdio.h> 51 #include<stdlib.h> 52 53 char *getmemory(int n){ 54 55 //不能q++的原因是:返回的q不是首地址。 56 char *qi; 57 int len=n*2+2; 58 if(NULL==(qi=(char *)malloc(sizeof(int)*len))){ 59 perror("cannot malloc"); 60 return NULL; 61 } 62 int i=0; 63 while(i<n){ 64 qi[i]='W'; 65 66 i++; 67 } 68 while(i<2*n){ 69 qi[i]='B'; 70 71 i++; 72 } 73 while(i<(2*n+2)){ 74 qi[i]='0'; 75 76 i++; 77 } 78 return qi; 79 } 80 81 void jiaohuan(char *qi,int i,int j){ 82 char temp; 83 temp=qi[i]; 84 qi[i]=qi[j]; 85 qi[j]=temp; 86 i++;j++; 87 temp=qi[i]; 88 qi[i]=qi[j]; 89 qi[j]=temp; 90 } 91 void si(char *qi){ 92 jiaohuan(qi,8,3); 93 jiaohuan(qi,3,7); 94 jiaohuan(qi,7,1); 95 jiaohuan(qi,1,6); 96 jiaohuan(qi,6,0); 97 } 98 void my_printf(char *qi,int m){ 99 int i=0; 100 for(i=0;i<m*2+2;i++){ 101 printf(" %c ",qi[i]); 102 } 103 printf("\n"); 104 } 105 106 void qijiaohuan(char *qi,int n,int m){ 107 108 if(n>3){ 109 jiaohuan(qi,n,2*n+2); 110 jiaohuan(qi,n,2*n); 111 n--; 112 my_printf(qi,m); 113 qijiaohuan(qi,n,m); 114 115 }else{ 116 si(qi); 117 my_printf(qi,m); 118 } 119 120 121 122 } 123 124 int main(){ 125 int n; 126 printf("请输入N的个数:\n"); 127 scanf("%d",&n); 128 char *qi; 129 130 qi=getmemory(n); 131 //int i=0; 132 my_printf(qi,n+1); 133 134 qijiaohuan(qi,n-1,n); 135 //si(qi); 136 137 138 139 140 141 return 0; 142 }
练习题:
注:标有(课堂)字样的为课上练习,其他为课下练习
基础题(50题)
1、(课堂)编写程序,输出“XXX欢迎来到动物园!”(XXX是自己的名字)。
2、(课堂)打印用*组成的字母C
3、交换杯子里的液体。使用不同的整数代表液体,变量代表杯子。
(课堂)方法1:中间变量法
(课堂)方法2:三步异或法
方法3:加和分减法
4、(课堂)使用宏定义PI来定义3.1415926,计算圆的面积。
5、(课堂)租船问题。
写程序计算游客需要付的租船的费用。租船每小时30元。游客输入租船时间,计算出租船费用。租船费用=时间*每小时钱数+押金。
要求押金与每小时钱数使用宏定义。
6、(课堂)求以下数字的原码、反码、补码。(可以使用计算器)
15(10进制)
0xE3A4(16进制)
7、输入一个整数(0~255),输出这个整数代表的ASCII码字符。
8、输入一个字符,判断这个字符是0~9之间的数字,还是大写字母,还是小写字母。若都不是输出错误信息。
9、计算输入时间的下一秒。例如输入12 15 32,输出12:15:33;输入21 59 59,输出22:00:00。
若输入非法时间(如输入小时是25、输入分钟/秒是61等情况)则报错。
10、(课堂)练习:从键盘输入5个学生的成绩(整数),要求输出总成绩(整数)和平均成绩(小数)
11、(课堂)读以下程序,猜想输出的结果,再执行程序检验自己的猜想
#include <stdio.h>
int main(void)
{
double y;
float a = 2.0;
int b =6,c=3;
y = a*b/c-1.5+'A';
printf("%f\n",y);
return 0;
}
12、(课堂)读以下程序,猜想输出的结果,再执行程序检验自己的猜想
#include <stdio.h>
int main()
{
int i = 8,j = 10,k = 12;
int m,n,p;
m = ++i;
n = j--;
p = (++m)*(n++)+(--k);
printf("i=%d,j=%d,k=%d\n",i,j,k);
printf("m=%d,n=%d,p=%d\n",m,n,p);
return 0;
}
13、(课堂)设
int a=3,b=4,c=5,d;
分别求出下列表达式的d的值(即判断此表达式真假)
1)d = a+b>c && b==c
2)d = a || b+c && b-c
3)d = !(a>b) && !c || 1
4)d = !(x=a)&&(y=b)&&0(x和y均为int型,求出x和y的值)
5)d = !(a+b)+c-1 && b+c/2
14、(课堂)输入3个整数,从小到大输出
15、(课堂)输入3个正整数作为3条线段的长度,判断这3条线段能否构成三角形。构成三角形的条件是:任意两边之和大于第三边
16、(课堂)输入一个年份(正整数),判断这年是否是闰年。闰年判断标准:年份能被4整除;如若遇到100的倍数,
则需判断年份能否被400整除。(逢4一闰,逢百不闰,逢400又闰)
17、(课堂)输入一个学生的成绩,输出该成绩对应的分数段。90~100为优,80~89为良,70~79为中,60~69为及格,
0~59为不及格,其他则输出错误信息。要求使用switch实现。
18、(课堂)运输公司对用户按路程计算费用。路程越远,每吨*千米运费折扣越高。计算运费公式如下:
freight = weight * distance * price * (1-discount);
路程与折扣的关系如下:
s<250:无折扣
250<=s<500:2%折扣
500<=s<1000:5%折扣
1000<=s<2000:8%折扣
2000<=s<3000:10%折扣
3000<=s:15%折扣
要求从键盘输入货运总重(单位吨)、货运路程(单位千米)、每吨*千米货运单价(单位元),输出总花费。
19、(课堂)求1+2+3+……+99+100=?。使用while()、do-while()和for()三种循环分别实现。
20、打印所有水仙花数。水仙花数是这样的三位数:各位数字的立方和等于其本身。如153就是一个水仙花数。
21、(课堂)打印斐波那契数列的前n项,其中n由键盘输入。斐波那契数列的特点如下:
F1=1 (n=1)
F2=1 (n=2)
Fn=Fn-1 + Fn-2 (n>=3)
22、(课堂)输出如下图形:
*
***
*****
*******
*********
……
其中需要输出几行由键盘输入。
23、(课堂)现有100元钱要买以下3种文具。其中一个笔记本20元,一套尺6元,一个笔4元,每样文具至少买1个。
列举出所有的购买方案,以及列举出所有花光100元的购买方案
24、(课堂)输出100~200间的所有素数
25、计算1+2+3+……+99+100=?,在执行加法之前由用户输入3个数,这3个数不参与运算。例如输入3、57和89,则最终结果等于4901。
26、编写一个程序,由键盘输入若干正整数,输入0代表输入完成。计算输入的数中的奇数的个数、总和、平均值;
计算输入的数中的偶数的个数、总和、平均值。
27、卡拉兹(Callatz)猜想:
对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去,最后一定在某一步得到n=1。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证(3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过1000的正整数n,简单地数一下,需要多少步才能得到n=1?
28、读懂以下程序,分析程序逻辑,画出流程图,说明程序的功能
#include<stdio.h>
int main()
{
int x,y;
printf("enter x:");
scanf("%d",&x);
y=0;
if(x!=0)
{
if(x>0)
y=1;
else
y=-1;
}
printf("x=%d\ny=%d\n",x,y);
return 0;
}
29、给定一个不多于5位的正整数,要求:
①求出它是几位数
②分别输出每一位数字(这里的位指十进制的位而非二进制的bit)
③将数字逆序。例如输入123,则输出321
30、使用公式求π的近似值
π/4 = 1 - 1/3 + 1/5 - 1/7 + ……
直到某一项的绝对值小于10^-6为止。
(提示:判断该数字是否小于10^-6,可以使用系统库函数fabs
fabs(f)>=1e-6//1e-6是10^-6的科学计数法表示方式
若要使用fabs()函数,则应包含头文件math.h
#include<math.h>
而且要在编译时添加-lm,即手动添加数学库libm.o
gcc qiupai.c -o qiupai -lm)
31、读懂以下程序,说明程序的功能
#include<stdio.h>
int main()
{
int m,n,r,m1,m2;
printf("请输入2个正整数:");
scanf("%d%d",&m1,&m2);
m=m1;
n=m2;
do{
r=m%n;
m=n;
n=r;
}while(r!=0);
printf("%d\n",m);
return 0;
}
32、一个数如果恰好等于它的所有的因子之和,则这个数就称为“完数”。例如6的因子有1、2、3,而1+2+3=6,因此6是一个完数。编程找出1000内所有的完数。
33、(课堂)思考这个宏定义错在哪里
#define S (r) PI*r*r//注意S与(r)之间有空格
34、我们在头文件(.h文件)中,经常看到这样的内容
#ifndef __H_INCLUDE__
#define __H_INCLUDE__
//头文件的实际内容
#endif
思考头文件的开头和结尾需要这样书写的原因。
35、(课堂)运行以下程序
int main()
{
char a,b;
a = getchar();
b = getchar();
putchar(a);
putchar(b);
return 0;
}
运行程序,输入x回车y回车,会发现输出的并不是xy,而是
x
思考这是为什么。
36、(课堂)使用数组存储斐波那契数列前40项,并输出
37、(课堂)从键盘输入10个学生的成绩,如果遇到大于100或者小于0的成绩需要提示输入错误重新输入。之后计算10个学生的总成绩和平均成绩
38、(课堂)冒泡排序
从键盘输入10个各不相同的整数,存储在数组中,使用冒泡排序法将数组排序并输出
冒泡排序:是一种简单的排序算法
1)比较相邻的元素和其身后的元素。如果第一个比第二个大,就交换他们两个。
2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。一次循环过后,最后的元素应该会是最大的数。
3)针对所有的元素重复以上的步骤,除了最后一个。
4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
39、(课堂)自定义一个3*4的矩阵,输出矩阵中值最大的元素,并输入其数组下标
40、(课堂)打印杨辉三角型前10行
41、给定任一个各位数字不完全相同的4位正整数,如果我们先把4个数字按非递增排序,再按非递减排序,然后用第1个数字减第2个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的6174,这个神奇的数字也叫Kaprekar常数。
例如,我们从6767开始,将得到
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
... ...
现给定任意4位正整数,请编写程序演示到达黑洞的过程。
42、(课堂)自定义2个字符数组,不使用系统提供的strcat()函数,实现strcat()函数功能。
43、(课堂)自定义2个字符数组,不使用系统提供的strcpy()函数,实现strcpy()函数功能。
44、(课堂)自定义2个字符数组,不使用系统提供的strcmp()函数,实现strcmp()函数功能。
45、(课堂)自定义1个字符数组,不使用系统提供的strlen()函数,实现strlen()函数功能。
46、输出以下图案。要求每行的字符数与每次偏移几个字符由用户输入。结束条件为最后一行开头与第一行末尾对齐或在其之后
**********
**********
**********
**********
**********
**********
//结束条件:最后一行开头与第一行末尾对齐或在其之后
47、按以下规律加密一段文字。
A->Z a->z
B->Y b->y
C->X c->x
……
Z->A z->a
其中不是字母的部分不加密。
48、规定一句话中以空格作为分词符。输入一句话,求一句话中最长单词的长度。例如:
I love China!
则最长单词是China!,最长单词长度是6
49、读以下程序,猜想程序的运行结果,然后上机验证
#include<stdio.h>
int main()
{
int i;
int lh,rh,le,re,m;
char *lefthand[] = {"╮","o","<","~\\"};
char *righthand[]= {"╭","o",">","/~"};
char *lefteye[] = {"╯","^","-","=",">","@","⊙"};
char *righteye[]= {"╰","^","-","=","<","@","⊙"};
char *mouth[] = {"Д","▽","_","ε","^"};
printf("请选择左手:\n");
for(i=0;i<=3;i++)
{
printf("%d.[%s] ",i+1,lefthand[i]);
}
printf("\n");
scanf("%d",&lh);
lh--;
printf("请选择右手:\n");
printf("推荐:%d.[%s]\n其他:",lh+1,righthand[lh]);
for(i=0;i<=3;i++)
{
if(i==lh)
continue;
printf("%d.[%s] ",i+1,righthand[i]);
}
printf("\n");
scanf("%d",&rh);
rh--;
printf("请选择左眼:\n");
for(i=0;i<=6;i++)
{
printf("%d.[%s] ",i+1,lefteye[i]);
}
printf("\n");
scanf("%d",&le);
le--;
printf("请选择右眼:\n");
printf("推荐:%d.[%s]\n其他:",le+1,righteye[le]);
for(i=0;i<=6;i++)
{
if(i==le)
continue;
printf("%d.[%s] ",i+1,righteye[i]);
}
printf("\n");
scanf("%d",&re);
re--;
printf("请选择嘴:\n");
for(i=0;i<=4;i++)
{
printf("%d.[%s] ",i+1,mouth[i]);
}
printf("\n");
scanf("%d",&m);
m--;
printf("%s(%s%s%s)%s\n",lefthand[lh],lefteye[le],mouth[m],righteye[re],righthand[rh]);
return 0;
}
50、围绕着山顶有10个圆形排列的洞,狐狸要吃兔子,兔子说:“可以,但必须先找到我,我就藏身于这十个洞中的某个洞。你从1号洞找,下次隔1个洞(即3号洞)找,第三次隔2个洞(即6号洞)找,再隔3个…以后在这个圆圈中如此类推,次数不限。”但狐狸从早到晚进进出出了1000次,仍没有找到兔子。
问:兔子可能藏身于哪(几)个洞中?
提高题:
1、编写程序,随机生成一个1~10内的数,让对方猜3次。如果3次内能猜中则输出“恭喜你”;若3次内猜不中则输出正确答案。
C语言中提供生成随机数的函数rand()
用法:
①所需头文件:
#include<math.h>
#include<time.h>
②生成随机数种子:
srand(time(0));
③生成某范围内的随机数。例如生成1~100内的随机数
int a = rand()%100+1;//将这个数取余100,会得到一个0~99之间的数,将这个数+1即可得到1~100之间的数
2、在上一题基础上,编写一个彩票程序。
彩票程序在后台随机生成1~35内的7个各不相同的数字。用户会输入一组7个数字,中奖规则:
猜中
7个500万
6个100万
5个1万
4个5000
3个500
0,1,2个没中奖
输出是否中奖及奖金。
3、判断一个矩阵中是否存在鞍点,若存在输出鞍点。鞍点是这样一个数字:在该行最大,在该列最小。例如:
1 2 6 4
5 6 7 8
9 10 11 12
则数字6(a[0][2])是鞍点。一个矩阵可能没有鞍点,可能拥有不止一个鞍点。
4、使用1、2、3、4四个数字能组成多少个无重复数字的三位数?输出这些三位数。
5、输入一个日期(年、月、日),计算该日期是这一年的第几天。注意判断闰年。
6、输出9*9乘法口诀表
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
……
7、输入2个正整数,求它们的最大公约数和最小公倍数
8、楼梯有n阶台阶,上楼可以一步上1阶,也可以一步上2阶,编程序计算n阶台阶共有多少种不同的走法
9、协助破案。假设已经查清,有A、B、C、D、E五个犯罪嫌疑人可能参与作案,但是不知道哪(几)个是真正的案犯。不过有证据表明:
⒈如果A参与了作案,则B一定也参与
⒉B和C两人中只有一人参与了作案
⒊C和D要么都参与作案,要么都没有参与
⒋D和E两个人中至少有一人参与了作案
⒌如果E作案,则A和D必定协助作案。
编程找出谁是真正的案犯(可能不止一人)
10、给定一个5位数,判断这个数字是否是回文数。例如12321是回文数,而12345就不是回文数。
11、自定义一个5*5矩阵,将这个矩阵转置。
12、约瑟夫环问题:
约瑟夫入狱,监狱内共有33个犯人。某日33名犯人围成一圈,从第一个犯人开始报数,报到数字7的犯人出列,被枪毙,下一名犯人重新从1开始报数。依次类推,直至剩下最后1名犯人可被赦免。聪明的约瑟夫在心里稍加计算,算出了最后枪毙的位置,他站在这个位置,最终避免了自己被枪毙,逃出升天。
问:约瑟夫算出的是哪个位置?
13、假设你收到了一行使用凯撒密码加密过的单词但不知道秘钥(偏移字母数),请破译这段密文。
密文:PELCGBTENCUL
提示:凯撒密码加密是一种字母替换加密算法,其加密原则是:将26个字母连接成环,明文的所有字母被后n位的字母替换得到密文。例如当n=3的时候替换规则是:
A--->D
B--->E
C--->F
……
X--->A
Y--->B
Z--->C
明文HELLO----->密文KHOOR
14、棋子移动问题
有2n(n>=4)个棋子排成一行,其中黑棋B有n个,白棋W有n个,并留有两个空格。例如,当n=4时排列如下所示:(W为白棋,B为黑棋,0为空格)
W W W W B B B B 0 0
当n=5时排列如下所示:(W为白棋,B为黑棋,0为空格)
W W W W W B B B B B 0 0
现在需要移动棋子,移动规则如下:
⒈每次必须同时移动相邻的两个棋子
⒉每次移动必须跳过若干棋子
⒊不能随意调换任意两个棋子的位置
目标:将所有的棋子移动为黑白棋相间的形式,中间不能有空格。
例如:当n=4时移动步骤如下:
起始: W W W W B B B B 0 0
第一步:W W W 0 0 B B B W B
第二步:W W W B W B B 0 0 B
第三步:W 0 0 B W B B W W B
第四步:W B W B W B 0 0 W B
第五步:0 0 W B W B W B W B(完成)
编程实现:从键盘输入n(n>=4),求每一步的棋子移动
15、以下是对“快速排序算法”的算法描述,请读懂这段文字,编写出快速排序算法函数QSort。
提示:函数的原型是:void QSort(int A[], int left, int right)
快速排序由C. A. R. Hoare在1962年提出,是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序算法的文字描述是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j;此时令循环结束。将key值赋值到i(或j)的位置。
6)递归操作数组A[]在key值左的左半部分。
7)递归操作数组A[]在key值右的右半部分。