江苏省高校计算机等级考试命题研究院 江苏省高校计算机等级考试辅导
2009春江苏计算机上机考试题型解析

上机分析典型试题

第一大类:数值类

题型1:素数问题

2009年三月考题:

程序功能:找出7个默森尼数。法国数学家默森尼曾提出下列公式:Mp=2^p-1。当p是素数并且Mp也是素数时,Mp为默森尼数,例如,p=5, Mp=2^5-1=31,531都是素数,因此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,n1n2差的绝对值得到n3,将n3的百位数字与个位数字交换得到n4;n3n4的和得到n5,n5一定是1089,n1n3是一位数或两位数,则在高位补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++)           /*通过遍历将s1s2进行比较两者是否相同*/

 {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

    -1  l0    3    2

运行结果;

  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-1j=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指向的a5列数组中存储的矩阵是否是Monge矩阵,若是则函数返回1,否则返回0

2.编写函数void change(int a[ ][5],int n),其功能是对a指向的n5列数组中的矩阵作如下转换,第一行与最后一行交换,第二行与倒数第二行交换,….直到每一行都交换过一次为止