2003年真题

二、

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 
 5 int dec(int a[],int n){
 6     if(n<=1)
 7         return 1;
 8     if(a[0]<a[1])//只要子序列第一个数和第二个数为非递减数列则说明该数列为非递减数列
 9         return 0;
10     return dec(a+1,n-1);
11 }
12 int main()
13 {
14     int a[]={5,5,4,3,2,1,0};
15     printf("%d\n",dec(a,sizeof(a)/sizeof(int)));
16     return 0;
17 }

功能:判断一个数组是否为非递增数列,若是则返回1,不是返回0

三、

这里需要注意:i<=strlen(s1),一定要加上等号,如果不加等号,当访问到最后一个单词时,由于i==strlen(s1)则跳出了循环,那么最后一个单词的长度是否比之前的大,就没有判断了。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include<string.h>
 4 int alph(char c){
 5     if(c>='a'&&c<='z'||c>='A'&&c<='Z')
 6         return 1;
 7     else
 8         return 0;
 9 }
10 
11 int main()
12 {
13     char s1[]="I am happy";
14     int i,len=0,length=0,flag=0,p,k;
15     for(i=0;i<=strlen(s1);i++){
16         if(alph(s1[i])){
17 
18             if(!flag){
19                 k=i;//记录这个新单词的第一个字母的位置
20                 flag=1;//表示接下来的一个字母是这个单词里的成员
21                 len++;
22             }else
23                 len++;
24 
25         }else{
26             flag=0;
27             if(len>length){
28                 length=len;
29                 p=k;
30                 len=0;
31             }
32         }
33     }
34 
35     printf("%d %d",length,p);
36     return 0;
37 }

运行结果:

四、

2.该程序功能:它能对文本文件进行拷贝,也能对二进制文件拷贝。
命令格式为: cpy  [/A] [/B] <文件名1> <文件名 2>
(1) /A表示按ASCII码方式进行拷贝。
(2) /B 表示按二进制方式进行拷贝,两种方式不能联合使用,否则
给出错误信息。
(3) <文件名1>是源文件,<文件名2>是目标文件。

这里需要注意的是feof(FILE *fp)这个函数的注意事项,具体看:https://www.cnblogs.com/industrial-fd-2019/p/13775377.html

用这个函数有固定模式(这样写一定不会出错):

 

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include<string.h>
 4 
 5 void copya(char *org,char *dest){
 6     FILE *fp1,*fp2;
 7     char c;
 8     if((fp1=fopen(org,"r"))==NULL){
 9         printf("error\n");
10         exit(1);
11     }
12     if((fp2=fopen(dest,"w"))==NULL){
13         printf("error\n");
14         exit(1);
15     }
16 
17     c=fgetc(fp1);
18     while(!feof(fp1)){
19         fputc(c,fp2);
20         c=fgetc(fp1);
21     }
22     fclose(fp1);
23     fclose(fp2);
24 }
25 
26 void copyb(char *org,char *dest){
27     FILE *fp1,*fp2;
28     char c;
29     if((fp1=fopen(org,"rb"))==NULL){
30         printf("error\n");
31         exit(1);
32     }
33 
34     if((fp2=fopen(dest,"wb"))==NULL){
35         printf("error\n");
36         exit(1);
37     }
38     c=fgetc(fp1);
39     while(!feof(fp1)){
40         fputc(c,fp2);
41         c=fgetc(fp1);
42 
43     }
44     fclose(fp1);
45     fclose(fp2);
46 }
47 
48 int main(int argc,char *argv[])
49 {
50     if(argc!=4){
51         printf("error\n");
52         exit(0);
53     }
54     if(!(strcmp(argv[1],"[/A]"))){
55         copya(argv[2],argv[3]);}
56     else if(!(strcmp(argv[1],"[/B]")))
57         copyb(argv[2],argv[3]);
58     else{
59         printf("usage:\n");
60         printf("dup[/A][/B]<file 1><file 2>\n");
61         exit(1);
62     }
63     return 0;
64 }

运行结果:

 

 

 

 

五、编程序(第1题6分,第2题8分,第3题15分,共29分)
说明: (1) 程序要加上必要的注释; (2) 按各题要求编程,否则不给分。 
1.含N个元素的整型数组a, 选任一 元素a[m], 将其它元素重新排列,使得a[i]≤a[m](i<m),a[j]≥a[m](j>m)。(注:不得对a数组排序)
例如: 
a数组元素为: 65,70,75, 80,85,60,55,50,45,若选择 a[0]=65,则结果为60,45,50,55,65,85, 80,75,70.

算法很简单:

用两个头尾指针 i,j

t=a[m];

i从开头扫描到a[i]>=t时停止,j从结尾开始扫描到a[j]<=t时停止,然后把两个数对调,直到i与j相遇时停止。最后得到的序列一定保证a[m]的左边都比a[m]小,右边都比a[m]大。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define N 20
 4 int a[N];
 5 
 6 void f(int a[],int n,int m){
 7     int t=a[m];
 8     int i=0,j=n-1;
 9     int c;
10     while(i<j){
11         while(a[i]<t) i++;
12         while(a[j]>t) j--;
13         c=a[i];
14         a[i]=a[j];
15         a[j]=c;
16     }
17 }
18 int main()
19 {
20     int i,n,m;
21     printf("n:");
22     scanf("%d",&n);
23     printf("m:");
24     scanf("%d",&m);
25     for(i=0;i<n;i++)
26         scanf("%d",&a[i]);
27     f(a,n,m);
28     for(i=0;i<n;i++)
29         printf("%d ",a[i]);
30     printf("\n");
31     return 0;
32 }

运行结果:

 

 

2.编写程序,生成如下序列的前n项。
1,2,1,2,3,2, 1,2.3.4.3,2, 1.2,3.4.5.4.3, 2,1, 2....

规律如下:

 

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 void f(int n){
 5     int count=0;
 6     int peak=2;
 7     int i=1;
 8     while(count<n){//就两个过程一个是上到高峰,然后就是跌倒谷底,反复这两个过程
 9         while(i<peak){
10             if(count==n)
11                 break;
12             printf("%d ",i++);
13             count++;
14         }
15         while(i>1){
16             if(count==n)
17                 break;
18             printf("%d ",i--);
19             count++;
20         }
21         peak++;
22     }
23 }
24 
25 int main()
26 {
27     int n;
28     printf("n:");
29     scanf("%d",&n);
30     f(n);
31     return 0;
32 }

运行结果如下:

 

 


3.程序实现两个整系数二元多项式的加法。例如,两个多项式为:
A(x,y)=5x^6y^3+4x^3y^2+7xy 和 B(x,y)= 5x^9y^3+4x^2y^3-7x^2y+10,结果为:
A(x,y)=5x^9y^3+5x^6y^3+8x^2y^3-7x^2y +7xy+10
要求:

(1)采用链表存储多项式,每一结点含三个域:指数域、系数域、指针域;

(2)将B多项式加到A上,结果是A所指的单链表,不另外生成新链表(否则不得分);

3) A、B所指的多项式链表的建立过程,写一函数(input)实现,以系数为0结束输入:相加过程写函数(add)实现, 在主函数中调用这两个函数。 不要求输出结果。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 typedef struct x_y{
  5     int x;
  6     int y;
  7 }EXP;
  8 
  9 typedef struct LNode{
 10     int coe;//系数域
 11     EXP exp;//指数域
 12     struct LNode *next;//指针域
 13 }LinkList;
 14 
 15 
 16 void input(LinkList **pa,LinkList **pb){
 17     //带头结点的尾插法
 18     LinkList *r,*s;
 19     int coe,x,y;//系数,x的指数,y的指数
 20     printf("A(x,y):输入格式为(系数,x的指数,y的指数)\n");
 21     *pa=(LinkList *)malloc(sizeof(LinkList));
 22     (*pa)->next=NULL;
 23     r=*pa;
 24     scanf("%d%d%d",&coe,&x,&y);
 25     while(coe){
 26         s=(LinkList *)malloc((sizeof(LinkList)));
 27         s->coe=coe;s->exp.x=x;s->exp.y=y;
 28         r->next=s;
 29         r=s;
 30         scanf("%d%d%d",&coe,&x,&y);
 31     }
 32     r->next=NULL;
 33 
 34     printf("B(x,y):输入格式为(系数,x的指数,y的指数)\n");
 35     *pb=(LinkList *)malloc(sizeof(LinkList));
 36     (*pb)->next=NULL;
 37     r=*pb;
 38     scanf("%d%d%d",&coe,&x,&y);
 39     while(coe){
 40         s=(LinkList *)malloc((sizeof(LinkList)));
 41         s->coe=coe;s->exp.x=x;s->exp.y=y;
 42         r->next=s;
 43         r=s;
 44         scanf("%d%d%d",&coe,&x,&y);
 45     }
 46     r->next=NULL;
 47 }
 48 
 49 void DeleteNode(LinkList **pre){
 50     LinkList *p=(*pre)->next;
 51     if(p!=NULL){
 52         (*pre)->next=p->next;
 53         free(p);
 54     }
 55 }
 56 
 57 void add(LinkList **pa,LinkList **pb){
 58     /*当为pa某一个结点时,扫一遍pb看有满足xy指数一致的项吗?若有则与A相加,若没有则往后移,再扫,重复,直到A扫完后,若B未扫完,还得把B链接到A,若B扫完,就完成了*/
 59     LinkList *p=(*pa)->next;
 60     LinkList *q=(*pb)->next;
 61     LinkList *q_i=q;
 62     LinkList *q_i_pre=*pb;
 63     LinkList *p_pre=*pa;
 64     int coe,x,y;
 65     while(p&&q){
 66         coe=p->coe;
 67         x=p->exp.x;
 68         y=p->exp.y;
 69         while(q_i){
 70             if(q_i->exp.x==x&&q_i->exp.y==y){
 71                 p->coe+=q_i->coe;
 72                 DeleteNode(&q_i_pre);
 73             }
 74             q_i_pre=q_i;
 75             q_i=q_i->next;
 76         }
 77         p_pre=p;
 78         p=p->next;
 79         q_i=q;
 80         q_i_pre=*pb;
 81     }
 82     LinkList *judge=(*pb)->next;
 83     while(judge){
 84         //当B不为空时,直接连接到A,采用尾插法
 85         (*pb)->next=(*pb)->next->next;//将judge这个结点从B中弄掉
 86         judge->next=p_pre->next;//将judge这个结点弄到A尾巴上去
 87         p_pre->next=judge;
 88         p_pre=judge;
 89         judge=(*pb)->next;
 90     }
 91 
 92 
 93 }
 94 void DisplayList(LinkList *L){
 95     LinkList *p=L->next;
 96     while(p!=NULL){
 97         printf("(%d,%d,%d)\n",p->coe,p->exp.x,p->exp.y);
 98         p=p->next;
 99     }
100 }
101 int main()
102 {
103     LinkList *A;
104     LinkList *B;
105     input(&A,&B);
106     printf("\n");
107     printf("A(x,y):\n");
108     DisplayList(A);
109     printf("\n");
110     printf("B(x,y):\n");
111     DisplayList(B);
112     add(&A,&B);
113     printf("\n");
114     printf("result_A(x,y):\n");
115     DisplayList(A);
116     return 0;
117 }

运行结果如下:

 

 

 

 输出结果: