复试上机刷题3 东华18上机真题

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处! https://sp4rkw.blog.csdn.net/article/details/88649018

第一题 改错题

题目如下:
给定程序modi.c中,fun函数的功能是:
先从键盘上输入一个3行3列矩阵的各个元素的值,然后输出主对角线元素之和。
请改正程序中的错误,使它能得出正确的结果。

注意:不要改动main函数,不得增行或删行(只能在已有代码行上修改),也不得更改程序的结构!

modi.c代码如下:

/*
注意:不要增加或删除任何行,那样将导致自动阅卷出错。
只能在已有的代码行上修改(注意:也不要删除本注释)。
*/
#include <stdio.h>
void fun()
{
	int a[3][3];
	int i;j;
	int sum;
	for (i=0;i<3;i++)
	{ 
		for (j=0;j<3;j++)
			scanf("%d", &a[I][j]);
	}
	for (i=1;i<=3;i++)
		sum=sum+a[i][i];
	printf("Sum=%d\n",sum);
}
int main()
{   
	fun();  
	return 0;
}

看到题目的第一眼感觉就是,不同于17年,没标注哪些地方有错误,不过总体依旧比较简单,改正之后的代码如下:

/*
注意:不要增加或删除任何行,那样将导致自动阅卷出错。
只能在已有的代码行上修改(注意:也不要删除本注释)。
*/
#include <stdio.h>
void fun()
{
	int a[3][3];
	int i,j;
	int sum=0;
	for (i=0;i<3;i++)
	{ 
		for (j=0;j<3;j++)
			scanf("%d", &a[i][j]);
	}
	for (i=0;i<3;i++)
		sum=sum+a[i][i];
	printf("Sum=%d\n",sum);
}
int main()
{   
	fun();  
	return 0;
}

共有四处改正:

  • 定义i,j时,中间的分号改为逗号
  • scanf读入值处i的大小写错了
  • 累加处for循环不对
  • sum初值没有赋

在这里插入图片描述

第二题 填空题

题目如下:
给定程序中,函数fun的功能是:计算形参x所指数组中N个数的平均值(规定所有数 均为正数),将所指数组中大于平均值的数据移至数组的前部,小于等于平均值的数据移 至x所指数组的后部,平均值作为函数值返回,在主函数中输出平均值和移动后的数据。

例如,有10个正数:
41 17 34 0 19 24 28 8 12 14,
平均值为:
19.700000
移动后的输出为:
41 34 24 28 17 0 19 8 12 14

请在程序的下划线处填入正确的内容并把下划线删除,使程序得出正确的结果。 注意:源程序存放在考生文件夹下的BLANK1.C中。 注意:不得增行或删行,也不得更改程序的结构!

BLANK1.C源码如下:

#include  <stdlib.h>
#include  <stdio.h>
#define   N   10
double fun(double  x[])
{ int  i, j;    double  s, av, y[N];
  s=0;
  for(i=0; i<N; i++)  s=s+x[i];
/**********found**********/
  av=__1__;
  for(i=j=0; i<N; i++)
    if( x[i]>av )
	{
/**********found**********/
      y[__2__]=x[i]; 
	  x[i]=-1;
	}
  for(i=0; i<N; i++)
/**********found**********/
    if( x[i]!= __3__) 
		y[j++]=x[i];
  for(i=0; i<N; i++)
	  x[i] = y[i];
  return  av;
}
main()
{ int  i;     double  x[N];
  for(i=0; i<N; i++){ x[i]=rand()%50; printf("%4.0f ",x[i]);}
  printf("\n");
  printf("\nThe average is: %f\n",fun(x));
  printf("\nThe result :\n",fun(x));
  for(i=0; i<N; i++)  printf("%5.0f ",x[i]);
  printf("\n");
}

补全之后代码如下:

#include  <stdlib.h>
#include  <stdio.h>
#define   N   10
double fun(double  x[])
{ int  i, j;    double  s, av, y[N];
  s=0;
  for(i=0; i<N; i++)  s=s+x[i];
/**********found**********/
  av=s/(double)i;
  for(i=j=0; i<N; i++)
    if( x[i]>av )
	{
/**********found**********/
      y[j++]=x[i];  
	  x[i]=-1;
	}
  for(i=0; i<N; i++)
/**********found**********/
    if( x[i]!= -1) 
		y[j++]=x[i];
  for(i=0; i<N; i++)
	  x[i] = y[i];
  return  av;
}
main()
{ int  i;     double  x[N];
  for(i=0; i<N; i++){ x[i]=rand()%50; printf("%4.0f ",x[i]);}
  printf("\n");
  printf("\nThe average is: %f\n",fun(x));
  printf("\nThe result :\n",fun(x));
  for(i=0; i<N; i++)  printf("%5.0f ",x[i]);
  printf("\n");
}

这题理解起来挺简单的,就是新开个数组,比平均值大的按顺序进新数组,且自身改为-1,之后将老数组中不为-1的全部读入新数组。

第三题 填空题

题目如下:
程序通过定义学生结构体数组,存储了若干名学生的学号、姓名和3门课的成绩。
函数fun的功能是将存放学生数据的结构体数组,按照学号从大到小排序(排序后输出学号依 次为:10004、10003、10002、10001)。
请在程序的下划线处填入正确的内容并把下划线删除,使程序得出正确的结果。
注意:源程序存放在考生文件夹下的BLANK2.C中。 注意:不得增行或删行,也不得更改程序的结构

BLANK2.C源码如下:

#include  <stdio.h>
#include  <string.h>
struct student {
  long  sno;
  char  name[10];
  float  score[3];
};
void fun(struct student  a[], int  n)
{
/**********found**********/
 __1__ t;
  int  i, j;
/**********found**********/
  for (i=0; i<__2__; i++)
    for (j=i+1; j<n; j++)
/**********found**********/
      if (__3__)
      {  t = a[i];   a[i] = a[j];  a[j] = t;  }
}
main()
{ struct student  s[4]={{10001,"ZhangSan", 95, 80, 88},{10002,"LiSi", 85, 70, 78},
                    {10004,"CaoKai", 75, 60, 88}, {10003,"FangFang", 90, 82, 87}};
  int  i, j;
  fun(s, 4);
  printf("The data after sorting :\n");
  for (j=0; j<4; j++)
  {  printf("No: %ld  Name: %-8s      Scores:  ",s[j].sno, s[j].name);
     for (i=0; i<3; i++)  printf("%6.2f ", s[j].score[i]);
     printf("\n");
  }
}

改过之后如下:

#include  <stdio.h>
#include  <string.h>
struct student {
  long  sno;
  char  name[10];
  float  score[3];
};
void fun(struct student  a[], int  n)
{
/**********found**********/
 struct student t;
  int  i, j;
/**********found**********/
  for (i=0; i<n; i++)
    for (j=i+1; j<n; j++)
/**********found**********/
      if (a[j].sno>a[i].sno)
      {  t = a[i];   a[i] = a[j];  a[j] = t;  }
}
main()
{ struct student  s[4]={{10001,"ZhangSan", 95, 80, 88},{10002,"LiSi", 85, 70, 78},
                    {10004,"CaoKai", 75, 60, 88}, {10003,"FangFang", 90, 82, 87}};
  int  i, j;
  fun(s, 4);
  printf("The data after sorting :\n");
  for (j=0; j<4; j++)
  {  printf("No: %ld  Name: %-8s      Scores:  ",s[j].sno, s[j].name);
     for (i=0; i<3; i++)  printf("%6.2f ", s[j].score[i]);
     printf("\n");
  }
}

太简单了,不解释了
在这里插入图片描述

第四题 编程题

题目如下:
请编写函数fun,其功能是:计算并输出给定数组(长度为9)中每相邻两个元素之平均值的平方根之和(求平方根的函数为sqrt)。

例如,
给定数组中的9个元素依次为12.0、34.0、4.0、23.0、34.0、45.0、18.0、3.0、11.0,
输出应为:s=35.951014。

注意:部分源程序存在文件prog1.c中。 请勿改动主函数main和其他函数中的任何内容,仅在函数fun的花括号中填入你编写的若干语句。

prog1.c源码如下:

#include <stdio.h>
#include <math.h>
double fun(double  x[])
{
}
NONO()
{/* 本函数用于辅助判卷,不要修改。但请不要尝试自己生成用于判卷的结果文件,投机取巧将得0分 */
  FILE *rf, *wf ; int i, j ; double s, a[9] ;
  rf = fopen("bc1.in", "r") ;
  wf = fopen("p1.out", "w") ;
  for(i = 0 ; i < 5 ; i++) {
    for(j = 0 ; j < 9 ; j++) fscanf(rf, "%lf", &a[j]) ;
    s = fun(a) ;
    fprintf(wf, "%lf\n", s) ;
  }
  fclose(rf) ; fclose(wf) ;
}

main()
{ double  s,a[9]={12.0,34.0,4.0,23.0,34.0,45.0,18.0,3.0,11.0};
  int  i;
  printf("\nThe original data is :\n");
  for(i=0;i<9;i++)printf("%6.1f",a[i]);  printf("\n\n");
  s=fun(a);
  printf("s=%f\n\n",s);
  NONO();
}

补充完代码之后的代码如下:

#include <stdio.h>
#include <math.h>
double fun(double  x[])
{
	double sum = 0;
	int i = 0,j=1;
	while(j<9){
		sum = sum +sqrt((x[i]+x[j])/2);
		i++;
		j++;
	}
	return sum;
}

NONO()
{/* 本函数用于辅助判卷,不要修改。但请不要尝试自己生成用于判卷的结果文件,投机取巧将得0分*/
  FILE *rf, *wf ; int i, j ; double s, a[9] ;
  rf = fopen("bc1.in", "r") ;
  wf = fopen("p1.out", "w") ;
  for(i = 0 ; i < 5 ; i++) {
    for(j = 0 ; j < 9 ; j++) fscanf(rf, "%lf", &a[j]) ;
    s = fun(a) ;
    fprintf(wf, "%lf\n", s) ;
  }
  fclose(rf) ; fclose(wf) ;
}

main()
{ double  s,a[9]={12.0,34.0,4.0,23.0,34.0,45.0,18.0,3.0,11.0};
  int  i;
  printf("\nThe original data is :\n");
  for(i=0;i<9;i++)printf("%6.1f",a[i]);  printf("\n\n");
  s=fun(a);
  printf("s=%f\n\n",s);
  NONO();
}

这题有一点小卡住,主要是在判断形参x的长度上陷入了误区,当时想的是既然没给长度参数,那就用sizeof()求一下,于是构造了:

int len1 = sizeof(x)/sizeof(x[0]);

之后发现len1为1,这里想了很久才想明白

因为,x是函数参数,到了本函数中,x只是一个指针(地址,系统在本函数运行时,是不知道a所表示的地址有多大的数据存储空间,这里只是告诉函数:一个数据存储空间首地址),所以,sizoef(x)的结果是指针变量x占内存的大小。x[0]double类型,sizeof(x[0])是8个字节,所以,结果永远是1。

后来想到main函数并没有读取数据只是直接给a数组赋值完成,所以长度我们已知是9,故直接搞定
在这里插入图片描述

第五题 编程题

题目如下:
请编写一个函数fun,它的功能是:数组num已从小到大排序(数组元素个数为n),现给定一个数m,要求返回最接近但不大于m的元素的位置(元素位置从0开始)。

程序运行后,
如果输入的数组元素为3, 5, 8, 12, 18, 20:

  • 如果m为8,则返回2
  • 如果m为7,则返回1
  • 如果m为1,则返回-1

注意:部分源程序存贮在文件prog2.c中。

要求:请衡量时间复杂度和空间复杂度,尽量设计高效算法。请在prog2.c最前面的 注释部分介绍自己的算法并分析时间复杂度。 请勿改动主函数main和其它函数中的任何内容,仅在函数fun的花括号中填入你编写的若干语句。

prog2.c源码如下:

/*
请在此描述你的算法,并分析时间复杂度
*/

#include<stdio.h>

int  fun(int  num[], int  n,int m)
{

}

NONO()
{/* 本函数用于辅助判卷,不要修改。但请不要尝试自己生成用于判卷的结果文件,投机取巧将得0分 */
    FILE *rf,*wf ;
    int a[100], i, j, p, m,n ;
    rf = fopen("bc2.in", "r") ;
    wf = fopen("p2.out", "w") ;
    for(i = 0 ; i < 6 ; i++)
    {
        fscanf(rf, "%d", &n) ;
        for(j = 0 ; j < n ; j++) fscanf(rf, "%d", &a[j]) ;
        fscanf(rf,"%d", &m);
        p = fun(a, n, m);
        fprintf(wf, "%d\n", p) ;
    }
    fclose(rf) ;
    fclose(wf) ;
}

int main ()
{
    int m,n , a[100];
    int i, subscript;
	printf("请输入元素个数:");
    scanf ( "%d", &n );
	printf("请按升序输入各元素(以空格分隔):");
    for ( i=0; i < n; i++ )
    {
        scanf ( "%d", &a[i] );
    }
	printf("请输入m:");
	scanf("%d", &m);
    subscript = fun(a, n, m);
    printf("The location is: %d\n", subscript);
    NONO();
    return 0;
}

补全之后的代码如下:

/*
使用一个for循环进行遍历,比m大,则向右移动,位置加1;
时间复杂度为o(n)
*/

#include<stdio.h>

int  fun(int  num[], int  n,int m)
{
	int flag = -1;
	for(int i = 0;i<n;i++){
		if(m>=num[i]){
			flag++;
		}
		else{
			break;
		}
	}
	return flag;
}

NONO()
{/* 本函数用于辅助判卷,不要修改。但请不要尝试自己生成用于判卷的结果文件,投机取巧将得0分 */
    FILE *rf,*wf ;
    int a[100], i, j, p, m,n ;
    rf = fopen("bc2.in", "r") ;
    wf = fopen("p2.out", "w") ;
    for(i = 0 ; i < 6 ; i++)
    {
        fscanf(rf, "%d", &n) ;
        for(j = 0 ; j < n ; j++) fscanf(rf, "%d", &a[j]) ;
        fscanf(rf,"%d", &m);
        p = fun(a, n, m);
        fprintf(wf, "%d\n", p) ;
    }
    fclose(rf) ;
    fclose(wf) ;
}

int main ()
{
    int m,n , a[100];
    int i, subscript;
	printf("请输入元素个数:");
    scanf ( "%d", &n );
	printf("请按升序输入各元素(以空格分隔):");
    for ( i=0; i < n; i++ )
    {
        scanf ( "%d", &a[i] );
    }
	printf("请输入m:");
	scanf("%d", &m);
    subscript = fun(a, n, m);
    printf("The location is: %d\n", subscript);
    NONO();
    return 0;
}

毫无难度,算法思想和时间复杂度都备注写在了上面
在这里插入图片描述

第六题 编程题

题目如下:
从数据结构中树的定义可知,除根结点外,树中的每个结点都有唯一的一个双亲结点。 根据这一特性,可用一组连续的存储空间(一维数组)存储树中的各结点。树中的结点除 保存结点本身的信息之外,还要保存其双亲结点在数组中的位置(即在数组中的下标。双亲的信息为-1则表示该结点为根结点),树的这种表示法称为双亲表示法。

树的每个结点的数据类型定义如下:

struct PTNode {
	char data; //结点数据域 
	int parent; //结点双亲在数组中的位置
};

树的数据类型定义如下:

#define MAX_TREE_SIZE 100 
struct PTree {
	struct PTNode nodes[MAX_TREE_SIZE]; //存储树中所有结点 
	int n; //树中共有 n 个结点,n 不超过 100
};

则下图 a 所示的树,按照双亲表示法存储结构,存储为图 b 所示形式(n 为 10)。
在这里插入图片描述已知一棵树已存储为以上形式,请编写函数 GetLowestLeavesCount,计算最下面一层叶子结点数目。GetLowestLeavesCount 的函数原型为: int GetLowestLeavesCount(struct PTree T)

其中, 形参 T 中保存了树中结点数目及图 b 所示的结点数组。 函数返回最下一层叶子结点的数目。
比如,对图 b 的树调用函数 GetLowestLeavesCount(T),返回结果为 6(因为 6 个叶子 结点均在最下面一层)。

部分代码在 prog3.c 中,请仅在 GetLowestLeavesCoun 函数中填入内容,完成程序。

要求:
在GetLowestLeavesCount函数前的注释部分简要介绍自己的算法。 请勿改动主函数main和其它已有函数中的任何内容,可以在函数 GetLowestLeavesCount的花括号中填入你编写的若干语句,允许增加自定义函数。
prog3.c 中,struct PTree CreateTree()函数用于从键盘输入树的双亲表示法的信息, 创建一棵树。输入的第一个数 n 表示树中结点数,此后有 n 行输入,每行表示一个结点 的信息,第一个信息为结点的数据,第二个信息为结点的双亲结点在数组中的位置

如输入:
10
a -1
b 0
c 0
d 0
e 1
f 1
g 1
h 2
i 3
j 3
则将创建图 b 所对应的树。 对此树调用函数 GetLeavesCount (T),返回结果为 6

如输入:
8
a -1
b 0
e 1
h 2
c 0
d 0
f 5
g 5
对此树调用函数 GetLeavesCount (T),返回结果为 1

prog3.c源码为:

#include <stdio.h>
void NONO();
#define MAX_TREE_SIZE 100
struct PTNode /*树的一个结点*/
{
   char data;
   int parent; /* 双亲位置域 */
};
struct PTree
{
   struct PTNode nodes[MAX_TREE_SIZE];
   int n; /* 结点数 */
};

/*
在这里简要介绍自己的算法
*/
int GetLowestLeavesCount(struct PTree T)
{
   
	

}
struct PTree CreateTree()
{
	int i,n;
	int parentId;
	char ch;
	struct PTree newTree;
    scanf("%d", &n);
	newTree.n=n;
    for (i = 0; i < n; i++)
    {
        scanf(" %c%d", &ch, &parentId);
		newTree.nodes[i].data=ch;
		newTree.nodes[i].parent=parentId;
    }
	return newTree;
}
int main() 
{
    struct PTree aTree;
	int count;
	aTree = CreateTree();
	count=GetLowestLeavesCount(aTree);
    printf("count:%d\n", count);
	NONO();
    return 0;
}
void NONO()
{/* 本函数用于辅助判卷,不要修改。但请不要尝试自己生成用于判卷的结果文件,投机取巧将得0分 */
    FILE *fp, *wf ;
	int i,j,n;
	int parentId;
	char ch;
	int count;
	struct PTree newTree;
    fp = fopen("bc3.in","r");
    wf = fopen("p3.out","w");
    for(i = 0 ; i < 6 ; i++) 
	{
		fscanf(fp, "%d", &n);
		newTree.n=n;
		for (j = 0; j < n; j++)
		{
			fscanf(fp," %c%d", &ch, &parentId);
			newTree.nodes[j].data=ch;
			newTree.nodes[j].parent=parentId;
		}
		count=GetLowestLeavesCount(newTree);
		fprintf(wf, "%d\n", count);
	}
    fclose(fp);
    fclose(wf);
}

补全函数之后的代码为:

#include <stdio.h>
void NONO();
#define MAX_TREE_SIZE 100
struct PTNode /*树的一个结点*/
{
   char data;
   int parent; /* 双亲位置域 */
};
struct PTree
{
   struct PTNode nodes[MAX_TREE_SIZE];
   int n; /* 结点数 */
};

/*
从最后一个节点向前遍历,判断每一个节点到根节点的距离;
和最后一个节点到根节点距离相同的节点均为最下面一层节点,到出现第一个节点到根节点距离变小为止
*/
int GetLowestLeavesCount(struct PTree T)
{
	int num = 0;
	int height=0,j=T.n-1;
	while(T.nodes[j].parent!=-1){
			height++;
			j = T.nodes[j].parent;
		}
	int h = height;
	int i;
	for(i = T.n-2;i>=0;i--){
		height = 0;
		j = i;
		while(T.nodes[j].parent!=-1){
			height++;
			j = T.nodes[j].parent;
		}
		if(height==h){
			num++;
		}
		else{
			break;
		}
	}
	return num;
}
struct PTree CreateTree()
{
	int i,n;
	int parentId;
	char ch;
	struct PTree newTree;
    scanf("%d", &n);
	newTree.n=n;
    for (i = 0; i < n; i++)
    {
        scanf(" %c%d", &ch, &parentId);
		newTree.nodes[i].data=ch;
		newTree.nodes[i].parent=parentId;
    }
	return newTree;
}
int main() 
{
    struct PTree aTree;
	int count;
	aTree = CreateTree();
	count=GetLowestLeavesCount(aTree);
    printf("count:%d\n", count);
	NONO();
    return 0;
}
void NONO()
{/* 本函数用于辅助判卷,不要修改。但请不要尝试自己生成用于判卷的结果文件,投机取巧将得0分 */
    FILE *fp, *wf ;
	int i,j,n;
	int parentId;
	char ch;
	int count;
	struct PTree newTree;
    fp = fopen("bc3.in","r");
    wf = fopen("p3.out","w");
    for(i = 0 ; i < 6 ; i++) 
	{
		fscanf(fp, "%d", &n);
		newTree.n=n;
		for (j = 0; j < n; j++)
		{
			fscanf(fp," %c%d", &ch, &parentId);
			newTree.nodes[j].data=ch;
			newTree.nodes[j].parent=parentId;
		}
		count=GetLowestLeavesCount(newTree);
		fprintf(wf, "%d\n", count);
	}
    fclose(fp);
    fclose(wf);
}

算法思路已经写入了备注,这题本来很简单,被我将i--写成了i++,调试了好久,难受
在这里插入图片描述

总结

依旧整体感觉很简单,考试多细心一点应该没啥问题,被最后一题的i--弄的快奔溃了,,,

展开阅读全文

没有更多推荐了,返回首页