2009春江苏计算机上机考试题型解析 |
上机分析典型试题 第一大类:数值类 题型1:素数问题 2009年三月考题: 程序功能:找出7个默森尼数。法国数学家默森尼曾提出下列公式:Mp=2^p-1。当p是素数并且Mp也是素数时,称Mp为默森尼数,例如,p=5, Mp=2^5-1=31,5和31都是素数,因此31是默森尼数;而Mp=2^11-1=2047,11是素数,2047不是素数,因此2047不是默森尼数. [编程要求] 1.编写函数void Mersenne(long a[ ],int m),其功能是求出前m个默森尼数并以此将它们保存到a指向的数组中, 2.编写main函数,调用Mersenne函数并保存前7个默森尼数,将运行结果输出到屏幕及结果文件myf2.out中,最后将考生的考号也保存到结果文件myf2.out中 【测试数据与运行结果】 3 7 31 127 8191 131071 524287 #include <stdio.h> #define N 7 int prime(long n) /*本函数的功能是判定素数*/ {long i; for(i=2;i<=n/2;i++) /*素数只能被1与自己整除,所以从2开始逐次比较*/ if(n%i==0) return 0; return 1; } void Mersenne(long a[ ],int m) {long f,n,k; int i=0; a[i++]=3; for(n=3;i<m;n+=2) {f=1; for(k=1;k<=n;k++) /*这个for循环实现2^n*/ f*=2; if(prime(n)&&prime(f-1)) /*两个都是素数则成立*/ a[i++]=f-1; } } void main() {long a[7]; int i;FILE *fp; fp=fopen("myf2.out","w"); /*建立文件myf2.out*/ if(fp==NULL) exit(0); Mersenne(a,N); for(i=0;i<N;i++) {printf("%8ld",a[i]);fprintf(fp,"%8ld",a[i]); } fprintf(fp,"\mMy exam number is:0112400123"); } 题型二:整数拆分 用一组整数验证命题,任意一个百位数字与个位数字不同的三位正整数n1在经过以下操作后一定会变换到1089:将n1的百位数与个位数字交换得到n2,求n1和n2差的绝对值得到n3,将n3的百位数字与个位数字交换得到n4;求n3与n4的和得到n5,n5一定是1089,若n1、n3是一位数或两位数,则在高位补0使其成为三位数 例如:n1:123,n2:321,n3:198(321,-123),n4:891,n5:1089(198+891) 【编程要求】 1.编写函数int fun(int a[ ],int b[ ], int n),其功能是用n指向数组的前n个整数验证上述命题,将所有符合命题的整数所在数组元素的下标依次保存到b指向的数组中,函数返回b数组中数据的个数 2.编写main函数,声明a数组并用测试数据初始化,用a数组作为实参调用fun函数,将a数组中所有符合命题的整数输出到屏幕及结果文件myf2.out中,最后将考生本人的准考证号字符串也保存到结果文件myf2.out中 【测试数据与运行结果】 测试数据:123 765 1 45 121 1345 131 67 696 3589 运行结果:123 765 1 45 67 #include <stdio.h> #define N 100 int fun(int a[ ],int b[ ], int n) {int i,x,y,z,s,t,m,k=0; for(i=0;i<n;i++) if(a[i]/1000<1) /*判断是三位正整数*/ {x=a[i]/100;y=a[i]/10%10;z=a[i]%10; /*各位数分离*/ if(x!=z) /*百位数字与个位数字不同*/ {s=z*100+y*10+x; t=s>a[i]?(s-a[i]): (a[i]-s); /*两者的差*/ x=t/100;y=t/10%10;z=t%10; m=z*100+y*10+x; if(t+m==1089) b[k++]=i; } } return k; } void main() {int a[N]={123,765,1,45,121,1345,131,67,696,3589},b[N],n,i; n=fun(a,b,10); for(i=0;i<n;i++) printf("%5d",a[b[i]]); } 第二大类:字符串类 题型:出现次数问题 函数merge的功能是:合并两个字符串集合为一个新集合,每个字符串在新集合中仅出现一次,函数返回新集合中字符串的个数 【测试数据与运行结果】 测试数据: s1集合:{“while”,”for”,”switch”,”if”,”break”,”continue”} s2集合:{“for”,”case”,”do”,”else”,”char”,”switch”} 运行结果: while for switch if break continue case do else char #include <stdio.h> #include <string.h> int merge(char s1[ ][10],char s2[ ][10],char s3[ ][10],int m,int n) {int i,j,k=0; for(i=0;i<m;i++) /*这个for循环实现将s1数组值传递给s3*/ strcpy(s3[k++],s1[i]); for(i=0;i<n;i++) /*通过遍历将s1与s2进行比较两者是否相同*/ {for(j=0;j<m;j++) if(strcmp(s2[i],s1[j])==0) break; if(j==m) /*如果不相同将s2[i]元素拷贝至s3数组中*/ strcpy(s3[k++],s2[i]); } return k; } void main() {int i,j; char s1[6][10]={"while","for","switch","if","break","continue"}, s2[6][10]={"for","case","do","else","char","switch"},s3[20][10]; j=merge(s1,s2,s3,6,6); for(i=0;i<j;i++) printf("%s ",s3[i]); } 第三大类:二维数组类 题型:行列变化问题 已知x数组中存储的n阶矩阵有一个鞍点(鞍点是指该位置上的数是所在行的最大数。同时也是所在列的最小数),程序实现将矩阵中鞍点所在列移动到最右侧。 【测试数据与运行结果】 测试数据; 1 3 2 0 4 6 5 -1 7 9 8 0 运行结果; An dian;a[0][1] 1 2 0 3 4 5 -1 6 7 8 0 9 -1 3 2 10 #include<stdio.h> #define N 4 /* 定义常量*/ void exchange(int a[][N]) {int i,j,k,f,t,m,mj; for(i=0;i<N;i++) {m=a[i][0]; mj=0;f=1; for(j=0;j<N;j++) /*这个for循环实现寻找一行的最大数*/ if(a[i][j]>m) {m=a[i][j]; mj=j;} for(k=0;k<N&&f;k++) /*这个for循环实现查找列中是否是最大数*/ if(a[k][mj]<m) f=0; if(k>=N)break; /*寻找到鞍点*/ } if(f) {printf("An dian;a[%d][%d]\n",i,mj); for(i=0;i<N;i++) /*这个for循环实现转换*/ { t=a[i][mj]; for(j=mj;j<N-1;j++) /*交换元素中的数值,实现数组元素向前移动*/ a[i][j]=a[i][j+1]; a[i][N-1]=t; } } } void main() {int x[N][N]={{1,3,2,0},{4,6,5,-1},{7,9,8,0},{-1,10,3,2}},i,j; for(i=0;i<N;i++) {for(j=0;j<N;j++) printf("%3d",x[i][j]); printf("\n"); } printf("\n"); exchange(x); for(i=0;i<N;i++) {for(j=0;j<N;j++) printf("%3d",x[i][j]); printf("\n"); } } 题型2:矩阵运算 先判断一个M×N矩阵是否是一个Monge矩阵,再对该矩阵作转换,判断变换后的M×N矩阵是否仍是Monge矩阵 如果一个M×N矩阵为Monge矩阵,当且仅当i=1,2,…,m-1和j=1,2,…,n-1时 A[i,j]+A[i+1,j+1]<=A[i,j+1]+A[i+1,j]成立 【编程要求】 1.编写函数int Monge(int a[ ][5],int n),其功能是判断a指向的a行5列数组中存储的矩阵是否是Monge矩阵,若是则函数返回1,否则返回0 2.编写函数void change(int a[ ][5],int n),其功能是对a指向的n行5列数组中的矩阵作如下转换,第一行与最后一行交换,第二行与倒数第二行交换,….直到每一行都交换过一次为止 |