二、填空题
2、对于正整数n输出其和等于n且满足以下限制条件的正整数和式,即组成和式的数字电左至右构成一个非递增的序列。

如: n=4
则程序输出为:
4=4
4=3+1
4=2+2
4=2+1+ 1
4=1+1+1+1

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define MAXN 100
 4 int a[MAXN];
 5 
 6 void rd(int n,int k){
 7     int i,j,t;
 8 
 9     for(j=n;j>=1;j--){
10         a[k]=j;
11        // printf("a[%d]=%d a[%d]=%d\n",k-1,a[k-1],k,a[k]);
12 
13        // printf("k=%d rd(%d,%d)\n",k,n,k);
14         if(j==n){
15                 t=1;
16                 while(t<=k&&a[t]<=a[t-1]) t++; //用于判断是否构成一个自左至右非递增的序列
17                 if(t>k){
18                     printf("%d=%d",a[0],a[1]);
19                     for(i=2;i<=k;i++)
20                         printf("+%d",a[i]);
21                     printf("\n");
22                 }
23         }else{
24             rd(n-j,k+1);
25             /*如果第k个位置上的数与n不想等,
26                 则继续递归到第k+1个位置继续判断第k+1个位置上的数与n(此时的n为n-j,因为上一个位置存放的是j)是否相等*/
27         }
28 
29     }
30 }
31 int main()
32 {
33     int test_data[]={3,4,5};
34     int i;
35     for(i=0;i<sizeof(test_data)/sizeof(int);i++){
36         a[0]=test_data[i];
37         rd(test_data[i],1);
38         printf("\n\n");
39     }
40     return 0;
41 }

输出结果如下:

 

3.、 以下程序其功能是将命令行中所列的文件依次在屏幕上显示,每显示完一个文件内容后, 用户按任意一键,则显示下一个文件。如果命令中所列的文件不能打开或没有给出文件名,则会显示相应的信息,命令的格式为:output 文件 1  文件2....

#include <stdio.h>
#include <stdlib.h>

void output(FILE *fptr){
    int c;
    while((c=getc(fptr))!=EOF)
        putchar(c);
}

int main(int argc,char *argv[])
{
    FILE *fp;
    int i;

    if(argc<2)
        printf("命令行参数错误:缺少文件名\n");

    else{
        for(i=1;i<argc;i++){
            if((fp=fopen(argv[i],"r"))==NULL)
                printf("文件<<%s>>不能打开。\n",argv[i]);
            else{puts(argv[i]);
                output(fp);

            }
            if(i!=argc-1){
                printf("\n按任意键,显示下一个文件\n");
                getchar();
            }
        }
    }
    return 0;
}

运行上述程序的流程:

首先安装好minw64,其次配置好环境变量,然后在*.c文件同一目录下创建多个文件,最后shift+鼠标右击选择在此处打开命令窗口进行 gcc *.c编译操作 得到*.exe文件 最后运行该文件 *.exe file1 file2...

配置环境变量流程如下:https://www.freesion.com/article/9311790608/

在命令窗口运行*.c程序流程如下:https://blog.csdn.net/zhengnianli/article/details/87738422

MinGW安装包如下:https://pan.baidu.com/s/1iku34F1RiGykS5E9IS9hKQ

运行结果如下:

 

三、编程题


1、有N个学生,每个学生记录包括学号、姓名、放绩,数据从键盘输入。要求找出成绩最高者的姓名和成绩。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define N 3
 4 typedef struct student{
 5     int id;//学号
 6     char name[20];//姓名
 7     float grade;//成绩
 8 }Stu;
 9 Stu students[N];//创建结构体数组
10 
11 int main()
12 {
13     int i,maxid=0;
14     printf("请输入%d个学生的记录\n",N);
15     for(i=0;i<N;i++){
16         printf("\n请输入第%d个学生的记录:\n",i+1);
17         printf("id:");
18         scanf("%d",&students[i].id);
19         getchar();
20         printf("name:");
21         gets(students[i].name);
22         printf("grade:");
23         scanf("%f",&students[i].grade);
24         if(students[i].grade>students[maxid].grade)
25             maxid=i;
26 
27     }
28     printf("记录中成绩最高的学生为:%s 成绩为:%6.1f\n",students[maxid].name,students[maxid].grade);
29     return 0;
30 }

运行结果如下:

 

 

注意:

 

 

 

2.将一个偶数分解成两个素数之和,并按下面格式输出结果。
如:
6=3+3
8=5+3
10= 7+3
10=5+5

 

 

 埃氏筛选法不太使用于素数的判断,素数判断的高效算法是哥德巴赫猜想:

哥德巴赫猜想: 哥德巴赫通过大量的数据猜测,所有不小于6的偶数,都可以表示为两个奇素数之和。后人将其称之,为“1+1"。并且,对学每个不小于9的奇数,都可以表示为三个奇素数之和。

分析:

质数还有一个特点,就是它总是等于 6x-1 或者 6x+1,其中 x 是大于等于1的自然数。

  如何论证这个结论呢,其实不难。首先 6x 肯定不是质数,因为它能被 6 整除;其次 6x+2 肯定也不是质数,因为它还能被2整除;依次类推,6x+3 肯定能被 3 整除;6x+4 肯定能被 2 整除。那么,就只有 6x+1 和 6x+5 (即等同于6x-1) 可能是质数了。所以循环的步长可以设为 6,然后每次只判断 6 两侧的数即可。

证明:令x≥1,将大于等于5的自然数表示如下:
······ 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ······
可以看到,不在6的倍数两侧,即6x两侧的数为6x+2,6x+3,6x+4,由于2(3x+1),3(2x+1),2(3x+2),所以它们一定不是素数,再除去6x本身,显然,素数要出现只可能出现在6x的相邻两侧。这里有个题外话,关于孪生素数,有兴趣的道友可以再另行了解一下,由于与我们主题无关,暂且跳过。这里要注意的一点是,在6的倍数相邻两侧并不是一定就是质数。
此时判断质数可以6个为单元快进,步长加大为6,加快判断速度,原因是,假如要判定的数为n,则n必定是6x-1或6x+1的形式,对于循环中6i-1,6i,6i+1,6i+2,6i+3,6i+4,其中如果n能被 6i,6i+2,6i+4整除,则n至少得是一个偶数,但是6x-1或6x+1的形式明显是一个奇数,故不成立;另外,如果n能被6i+3整除,则n至少能被3整除,但是6x能被3整除,故6x-1或6x+1(即n)不可能被3整除,故不成立。综上,循环中只需要考虑6i-1和6i+1的情况,即循环的步长可以定为6,每次判断循环变量k和k+2的情况即可。

 

当到达for时,只剩下满足条件的6x+5或者6x+1了,这个数一定是奇数,那么就只需判断这个数能否被奇数整除,6x+5或者6x-1一定不能够被3整除,所以从5开始.(其实对于if判断没咋弄懂......)

#include <stdio.h>
#include <stdlib.h>

int IsPrime(int n){
    int i;
    for(i=2;i*i<=n;i++){
        if(n%i==0)
            return 0;//不是素数
    }
    return 1;
}

int main()
{
    int n,i;
    printf("请输入一个偶数:");

    while((scanf("%d",&n))!=EOF){
        if(n%2==0&&n>2){
            for(i=2;i<=n/2;i++){
                if(IsPrime(i)&&IsPrime(n-i)){
                    printf("%d=%d+%d\n",n,i,n-i);
                }
            }
        }else if(n<=2){
            printf("您输入的偶数小于等于2请重新输入...\n");
        }else if(n%2!=0){
            printf("您输入的数不是偶数请重新输入...\n");
        }
        printf("请输入一个偶数:");

    }
    return 0;
}

运行结果如下:

 

 

3、将自然数按下图所示的次序存到NxN的二维数组A中。(注:下图所示是一个5X5的二维数组,箭头是提示自然数

出现的顺序。)

 

分析如图所示:

 

 

 

 

 代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define N 5
 4 int A[N][N];
 5 
 6 
 7 int main()
 8 {
 9     int left=0,right=0,up=0,down=0;//左减右加,上减下加
10     int num=1;
11     int i,j;
12     A[0][0]=1;
13     for(i=0;i<N-1;i++){
14 
15         if(i%2==0){//操作:右下左
16             right++;
17             A[up+down][left+right]=++num;
18             for(j=1;j<=i+1;j++){
19                 down++;
20                 A[up+down][left+right]=++num;
21             }
22 
23             for(j=1;j<=i+1;j++){
24                 left--;
25                 A[up+down][left+right]=++num;
26             }
27         }else{
28             //操作:下右上
29             down++;
30              A[up+down][left+right]=++num;
31             for(j=1;j<=i+1;j++){
32                 right++;
33                 A[up+down][left+right]=++num;
34             }
35             for(j=1;j<=i+1;j++){
36                 up--;
37                 A[up+down][left+right]=++num;
38             }
39         }
40 
41     }
42 
43     for(i=0;i<N;i++){
44         for(j=0;j<N;j++)
45             printf("%4d",A[i][j]);
46         printf("\n");
47     }
48     return 0;
49 }

运行结果如下: