提高题:
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之间的数
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 #include<math.h> 43 44 int main(){ 45 /* 46 int a ; 47 int i=0; 48 while(i!=3){ 49 a = srand(time(0))%10+1; 50 printf("!!!!!!!!!!%d\t",a); 51 i++; 52 } 53 54 55 56 int a ; 57 while(a!=3){ 58 a = rand()%10+1; 59 printf("%d\t",a); 60 } 61 */ 62 63 int a ; 64 a = srand(time(0))%100+1; 65 int i=0; 66 for(i=0;i<3;i++){ 67 int b; 68 printf("\n输入猜测值:"); 69 scanf("%d",&b); 70 if(a==b){ 71 printf("888恭喜你!"); 72 return 0; 73 } 74 } 75 76 printf("%d是正确答案: ",a); 77 78 79 return 0; 80 }
2、在上一题基础上,编写一个彩票程序。
彩票程序在后台随机生成1~35内的7个各不相同的数字。用户会输入一组7个数字,中奖规则:
猜中
7个500万
6个100万
5个1万
4个5000
3个500
0,1,2个没中奖
输出是否中奖及奖金。
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 int main(){ 19 20 21 22 23 return 0; 24 }
3、判断一个矩阵中是否存在鞍点,若存在输出鞍点。鞍点是这样一个数字:在该行最大,在该列最小。例如:
1 2 6 4
5 6 7 8
9 10 11 12
则数字6(a[0][2])是鞍点。一个矩阵可能没有鞍点,可能拥有不止一个鞍点。
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 }
4、使用1、2、3、4四个数字能组成多少个无重复数字的三位数?输出这些三位数。
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 }
5、输入一个日期(年、月、日),计算该日期是这一年的第几天。注意判断闰年。
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 }
6、输出9*9乘法口诀表
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
……
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 }
7、输入2个正整数,求它们的最大公约数和最小公倍数
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 }
8、楼梯有n阶台阶,上楼可以一步上1阶,也可以一步上2阶,编程序计算n阶台阶共有多少种不同的走法
1 #if 0 2 8、楼梯有n阶台阶,上楼可以一步上1阶,也可以一步上2阶,编程序计算n阶台阶共有多少种不同的走法 3 解题思路: 4 一。全部是一阶 5 二。有一个二阶 6 三。有两个二阶 7 四。以此类推到二阶最多的情况。 8 五。对每种情况进行全排序 9 10 111.....1111 11 2..2 12 将2插入1看有多少情况 13 2插到2旁边是一样的。 14 15 16 #endif 17 #include<stdio.h> 18 19 int main(){ 20 int taijie; 21 printf("输入台阶数:\n"); 22 scanf("%d",&taijie); 23 int liangjie=0,sum=0; 24 25 while((taijie-2*liangjie)>=0){ 26 int yijie=taijie-2*liangjie; 27 int zoufa=1; 28 //i等于2阶的个数,代表插入几次; 29 int i=liangjie; 30 while(i){ 31 zoufa*=(yijie+1); 32 33 i--; 34 } 35 36 37 printf("有%d步为两阶,走法%d种\n",liangjie,zoufa); 38 39 sum+=zoufa; 40 ++liangjie; 41 } 42 43 printf("\n总共有%d种\n",sum); 44 return 0; 45 }
9、协助破案。假设已经查清,有A、B、C、D、E五个犯罪嫌疑人可能参与作案,但是不知道哪(几)个是真正的案犯。不过有证据表明:
⒈如果A参与了作案,则B一定也参与
⒉B和C两人中只有一人参与了作案
⒊C和D要么都参与作案,要么都没有参与
⒋D和E两个人中至少有一人参与了作案
⒌如果E作案,则A和D必定协助作案。
编程找出谁是真正的案犯(可能不止一人)
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 }
10、给定一个5位数,判断这个数字是否是回文数。例如12321是回文数,而12345就不是回文数。
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 }
11、自定义一个5*5矩阵,将这个矩阵转置。
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 }
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
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 }
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值右的右半部分。