2018上半年程序员考试真题及答案-下午卷.doc
2018上半年程序员考试真题及答案-下午卷试题一阅读以下说明和流程图,填写流程图中的空缺,将解答填入答题纸的对应栏内。【说明】如果一个自然数N恰好等于它所有不同的真因子(即N的约数以及1,但不包括N)之和S,则称该数为“完美数”。例如6123,28124714,所以6和28都是完美数。显然,6是第1个(即最小的)完美数。下面流程图的功能是求500以内所有的完美数。【流程图】循环开始框中要注明:循环变量初始值,终值,步长,步长为1时可以缺省。如果某自然数小于其所有真因子之和(例如2412346812),则称该自然数为亏数:如果某自然数大于其所有真因子之和(例如8124),则称该自然数为贏数如果某自然数等于从1开始的若干个连续自然数之和(例如101234)则称该自然数为三角形数数。据此定义,自然数496是( )。供选择答案:(1)A.亏数 B.赢数 C.完美数,非三角形数 D.完美数和三角形数【答案】(1)2(2)N%K(3)S+K(4)S(5)D 【解析】 流程图的功能是求500以内所有的完美数,N的值范围是6500,因此N是需要判断是否为完美数,首先需要求出N的所有真因子,然后再判断N和真因子之和是否相等,从流程图可以看出S是保存真因子和的变量,K是保存真因子的变量,因此K的初始值是2,终值是N/2,因此第(1)空处填写:2;判断K是否为N的真因子,即判断N%K(N除以K取余)是否为0,第(2)空填写:N%K;当K为N的真因子时,需要计算所有K的和,即S=S+K,第(3)空填写:S+K;最后判断N和S是否相等,第(4)空填写:S。496的真因子有:1、2、4、8、16、31、62、124、248,1+2+4+8+16+31+62+124+248=496;因此496是完美数,同时496=(1+2+3+4+30+31),因此496是完美数和三角形数。试题二阅读以下说明和C代码,填写程序中的空(1)(5),将解答写入答题纸的对应栏内。【说明】直接插入排序是一种简单的排序方法,具体做法是:在插入第i个关键码时,k1,k2,ki-1已经排好序,这时将关键码ki依次与关键码ki-1,ki-2,进行比较,找到ki应该插入的位置时停下来,将插入位置及其后的关键码依次向后移动,然后插入ki。例如,对17,392,68,36按升序作直接插入排序时,过程如下:第1次:将392(i1)插入有序子序列17,得到17,392;第2次:将68(i2)插入有序子序列17,392,得到17,68,392;第3次:将36(i3)插入有序子序列17,68,392,得到17,36,68,392,完成排序。下面函数 insertSort用直接插入排序对整数序列进行升序排列,在main函数中调用insertSort并输出排序结果。 【C代码】void insert Sort(int data,int n)/*用直接插入排序法将data0 datan-1中的n个整数进行升序排列*/ int i,j; int tmp; for(i=1; i<n;i+) if(dataidatai-1) /将datai插入有序子序列data0datai-1 tmp=datai; /备份待插入的元素 datai=(1); for(j=i-2;j>=0 && dataj > tmp;j) /查找插入位置并将元素后移 (2); (3)=tmp; /插入正确位置 /*if*/ /*for*/*insertSort*/int main() int *bp,*ep; int n,arr=17,392,68,36,291,776,843,255; n = sizeof(arr) / sizeof(int); insertSort(arr,n); bp=(4); ep = arr+n; for(;bp<ep; bp+) /按升序输出数组元素 printf("%dt",(5)); return 0;【答案】(1)datai-1(2)dataj+1=dataj(3)dataj+1(4)arr(5)*bp【解析】 直接插入排序法是将关键码插入已经排好的序列中,因此将datai插入序列data0datai-1中,此时序列data0datai-1已经按照升序排列好,而datai应插入位置前的数据应该比datai小,而插入位置后的数据应比datai大,在if语句中判断datai<datai-1中可以看出,在进行插入运算时,是从序列data0datai-1最后一个数据datai-1向前逐一进行比较,若datai>=datai-1,则将datai插入到di-1后;若datai<datai-1,datai需要与datai-2进行比较,如此依次进行,此时需要将datai备份并将datai-1后移,即temp=datai; datai=datai-1;之后是进行比较,即for(j=i-2;j>=0&&dataj>tmp;j-)循环,从datai-2开始向前逐一比较,即j从i-2开始向0循环,若dataj>tmp,则进行for循环,此时需要将dataj即datai-2的值后移,使得datai-1=datai-2,即dataj+1=dataj,然后j-,用tmp与dataj进行比较,如果tmp< dataj,则说明tmp应放在dataj之前,那么dataj需要继续往后移动。所以dataj+1= dataj。 当该循环结束时,此时有2种情况:(1)j=-1<0,此时data0>tmp;应使得data0后移,即data1=data0,data0=tmp,因此第3空填写dataj+1;(2)dataj<=tmp;此时需要将tmp插入到dataj后,即dataj+1=tmp。在main函数中调用insertSort函数并输出数组元素,在for(; bp<ep;bp+)中循环变量是bp,因此输出的是bp指向的数组元素,即调用insertSort函数后返回的数组arr,因此bp=arr(bp是指针变量,数组名arr可以直接将数组地址传递给bp);在printf函数中输出bp;因此printf(“%dn”,*bp)。试题三阅读以下C代码,回答问题1至问题3,将解答填入答题纸的对应栏内。【C代码1】float adjustSalary(int service_year,int age,float salary) if( service_year <=5 ) if( age > 30 ) salary *= 1.2; else salary *= 2.0; return salary;【C代码2】void foo(int coin) switch (coin) case 1: printf("Centn"); case 5: printf("Nicke1n");break; case 10: printf("Dimen"); case 25: printf("Quartern"); 【C代码3】int getSum(int n)int t, i = 0, sum = 0;while ( i < n ) scanf("%d", &t); if( t<0 ) continue;sum += t; i+; return sum; 【问题1】(3分)对于【C代码1】,写出下面的函数调用后x1、x2和x3的值。x1 = adjustSalary(1,25,9000.0);x2 = adjustSalary(8,32,7000.0);x3 = adjustSalary(5,41,5000.0); 【问题2】(6分)(1)写出函数调用为foo(1)的输出结果;(2)写出函数调用为foo(5)的输出结果;(3)写出函数调用为foo(10)的输出结果;(4)写出函数调用为foo(25)的输出结果。 【问题3】(6分)(1)简要说明【C代码3】中的函数getSum()的功能;(2)程序员小王将函数getSum改写后得到下面的函数getSum_v2(即用for语句来描述循环)。请问,getSum_v2的功能是否与【C代码3】的getSum完全相同,若不同,请说明原因。答案:【问题1】(1)x1=9000.000000(2)x2=14000.000000(3)x3=6000.000000【解析】 对于x1,service_year=1,age=25,salary=9000.0,首先判断service_year<=5,因此再判断age<30,不进行任何运算,salary仍为9000.0,由于salary为float类型数据,因此输出为9000.000000。 对于x2,service_year=8,age=32,salary=7000.0,首先判断service_year>5,因此直接进行else中的运算,salary=7000.0*2.0=14000.0,由于salary为float类型数据,因此输出为14000.000000。 对于x3,service_year=5,age=41,salary=5000.0,首先判断service_year<=5,因此再判断age>30,进行运算salary=5000.0*1.2=6000.0,由于salary为float类型数据,因此输出为6000.000000。【问题2】(1)foo(1):Cent Nickel(2)foo(5):Nickel(3)foo(10):Dime Quarter(4)foo(25):Quarter【解析】foo(1):coin=1,执行printf(“Centn”),输出Cent并回车,继续执行printf(“Nickeln”),输出Nickel并回车,再执行break,结束foo函数。foo(5):coin=5,执行printf(“Nickeln”),输出Nickel并回车,再执行break,结束foo函数。foo(10):coin=10,执行printf(“Dimen”),输出Dime并回车,继续执行printf(“Quartern”),输出Quarter并回车,结束foo函数。Foo(25):coin=25,执行printf(“Quartern”),输出Quarter并回车,结束foo函数。【问题3】(1)函数getSum()是求n个不小于0的整数之和。(2)函数getSum_v2的功能与函数getSum不同,getSum()是求n个不小于0的整数之和,计算和的数目总数是n个,而getSum_v2是总共输入了n个数,这n个数种有大于等于0,也有小于0的数,最终只把大于等于0的数进行求和,因此最终计算的和的个数有可能是小于n的。 【解析】(1)函数getSum()是求n个不小于0的整数之和。(2)函数getSum_v2的功能与函数getSum不同,原因:在getSum中,当t<0时,继续运行scanf函数获得t,而不会运行i+运算,i的值不会改变,最终会获得n个不小于0的整数并求和;而在getSum_v2中,当t<0时,首先进行i+,再继续scanf函数,因此当输入的数出现负值时,会导致最终运算的值可能少于n个。试题四阅读以下说明和C代码,填写代码中的空(1)(6),将解答写入答题纸的对应栏内。【说明】下面的C代码在输入的100个英文单词中找出最小单词和最大单词。约定每个单词是仅由英文字母构成的字符串,且都不超过20个字符。单词的大小按照字典序定义。例如,单词“entry”大于“enter”、“art”小于“ article”、“an”等于“An”。 【C代码】#include <stdio.h>#define NUMBER 100int isValid(const char *s1); /若字符串s1仅包含英文字母则返回1,否则返回0char toLower(char ch); /将大写字母转换为小写字母int usr_strcmp(char *s1, char *s2); /比较字符串s1和s2,相等时返回0, /s1大则返回正整数,s1小则返回负整数void usr_strcpy(char *s1,const char *s2); /字符串s2拷贝给s1int main() char word32; char maxWord32="", minWord32 ="" int numWord=0; while(num Word<NUMBER) scanf("%s",(1)); /输入一个单词存入word if(is Valid(word) if (0=num Word) usr_strcpy(min Word,word);usr_strcpy(max Word,word); num Word+; if((2)>0) /调用usr_strcmp比较单词 usr_strcpy(max Word, word); /用max Word记下最大单词 else if((3)<0) /调用usr_strcmp比较单词 usr_strcpy(min Word,word); /用min Word记下最小单词 printf("max Word=%s min Word=%sn",max Word,min Word); return 0;int is Valid(const char *s) for(; *s ; s+) if(!(*s>='a' && *s<='z') && !(*s>='A' && *s<='Z') return 0; return 1; char toLower(char ch) /若ch为大写字母则返回其小写形式,否则直接返回原字符 if(ch>='A' && ch<='Z') ch=(4)+'a' return ch; int usr_strcmp(char *s1,char *s2) /按字典序比较两个英文单词,若s1表示的单词大,则返回正整数, /若s1表示的单词小,则返回负整数;否则返回0 for(;(5);) if(toLower(*s1)=toLower(*s2) s1+,s2+; else break; return(toLower(*s1) - toLower(*s2);void usr_strcpy(char *s1,const char *s2) /将s2表示的字符串复制给s1 for(;(6);) *s1+= *s2+; *s1=0;【答案】(1)word(2)usr_strcmp(word, maxWord)(3)usr_strcmp(word, minWord)(4)ch-A(5)*s1!=0&&*s2!=0或*s1|*s2等价表示(6)*s2!=0或*s2等价表示【解析】(1)scanf函数是将输入的数据赋值给相应的变量,在格式字符串后需要取变量地址,即将数据赋值给相应地址的变量,word是数组名,因此可以直接作为地址。(2)调用usr_strcmp比较单词,当usr_strcmp返回的值为正整数时,调用usr_strcpy将word值赋值给maxWord,因此此处是比较word和maxWord,即usr_strcmp(word, maxWord)(3)调用usr_strcmp比较单词,当usr_strcmp返回的值为负整数时,调用usr_strcpy将word值赋值给minWord,因此此处是比较word和minWord,即usr_strcmp(word, minWord)(4)toLower函数是将大写字母转换为小写字母,if函数是判断ch是否为大写字母,当ch为大写的时候,将ch转换为小写,小写是在a的基础上加上一个值得到,例如b=1+a,这个值便是大写字母和A之间的差值,即例子中1为B-A,因此此处填写ch-A(5)usr_strcmp是比较两个英文单词,是需要对s1和s2中的字符逐一比较,因此在for循环中进行比较,for循环的判断条件是s1和s2中的字符是否为0,因此此处填写*s1!=0&&*s2!=0(6)usr_strcpy是将s2复制给s1,是需要将s2中的字符逐一赋值给s1,因此在for循环中进行赋值,for循环的判断条件是s2中的字符是否为0,因此此处填写*s2!=0试题五阅读以下说明和Java程序,填写程序中的空(1)(6),将解答写入答题纸的对应栏内。【说明】以下Java代码实现一个简单绘图工具,绘制不同形状以及不同颜色的图形。部分接口、类及其关系如图51所示。【Java代码】interface DrawCircle /绘制圆形 public(1);class RedCircle implements DrawCircle /绘制红色圆形 public void drawCircle(int radius,int x, int y) System.out.println("Drawing Circlered,radius:" + radius + ",x:" + x + ",y:" +y+ ""); class GreenCircle implements DrawCircle /绘制绿色圆形 public void drawCircle(int radius, int x, int y) System.out.println("Drawing Circlegreen,radius:" +radius+ ",x: " +x+ ",y: " +y+ ""); abstract class Shape /形状 protected (2); public Shape(DrawCircle drawCircle) this.drawCircle = drawCircle; public abstract void draw();class Circle extends Shape /圆形 private int x,y,radius; public Circle(int x,int y,int radius,DrawCircle drawCircle) (3); this.x = x; this.y = y; this.radius = radius; public void draw() drawCircle.(4); public class DrawCircleMain public static void main(String args) Shape redCirclenew Circle( 100,100,10,(5));/绘制红色圆形 Shape greenCirclenew Circle(200,200,10,(6));/绘制绿色圆形 redCircle.draw(); greenCircle.draw(); 【答案】(1)void drawCircle (int radius,int x,int y)(2)DrawCircle drawCircle(3)super.drawcircle=drawcircle(4)drawCircle(radius,x,y)(5)new redCircle(6)new greenCircle 【解析】第一空是填接口里面的方法,在接口的实现里面找,可以发现应该填void drawCircle (int radius,int x,int y)。第二空可以根据后面this drawCircle=drawCircle判断,这里应该有一个drawCircle属性,因此应该填)DrawCircle drawCircle。第三空这里用super,用super. drawcircle来引用父类的成员。第四空调用drawCircle(radius,x,y)方法。第五、六空分别创建一个红色圆形对象和一个绿色圆形对象作为Circle里面的实参。