C基础的练习集及测试答案(提高题)


提高题:
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 01,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、23、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值右的右半部分。

posted @ 2018-08-12 20:43  蓝勃斐重新开始  阅读(583)  评论(0编辑  收藏  举报