/*---------------
【程序填空】
-----------------
题目:验证任意一个大于1的正整数都可以找到
一串连续奇数,它们的和等于该整数的立方。
例如:4的立方等于64,64=1+3+5+7+9+11+13+15
程序运行结果如下:
3的立方等于27, 27=7+9+11
4的立方等于64, 64=1+3+5+7+9+11+13+15
6的立方等于216, 216=7+9+11+13+15+17+
19+21+23+25+27+29
------------------------------------------------------------------------
注意:在填空标志处填写答案,并删除填空标志,勿改动程序中的其他部分。
----------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
int check(int n)
{
int i,j,k,sum,p;
k=n*n*n;
for(i=1; i<k/2; i+=2)
{
j=i;
/*************SPACE************/
for(sum=0;【?】;j=j+2)
sum=sum+j;
if(sum==k)
return i;
}
if(i>=k/2)
printf("error!");
}
int main(void)
{
int s[3]= {3,4,6};
int i,sum,cu,p;
for(i=0; i<3; ++i)
{
p = check(s[i]);
cu = s[i]*s[i]*s[i];
printf("%d的立方等于%d,\t%d=",s[i],cu,cu);
sum=p;
/*************SPACE************/
while(【?】)
{
printf("%d+",p);
p+=2;
sum+=p;
}
printf("%d\n",p);
}
return 0;
}
答案:
=======(答案1)=======
sum<k
k>sum
sum<n*n*n
n*n*n>sum
=======(答案2)=======
sum!=cu
sum<cu
cu>sum
cu!=sum
s[i]*s[i]*s[i]!=sum
sum!=s[i]*s[i]*s[i]
s[i]*s[i]*s[i]>sum
sum<s[i]*s[i]*s[i]
解析:
这个序列数肯定能找到,下面证明。
假设s为大于1的奇数,可找到一个数p=s*s,以p为中点,在p的左右两各找(s-1)/2个连续的奇数,这s个奇数分别为:p-s+1, p-s+3, …, p-2, p, p+2, …, p+s-1。例如,设s=7, p=s*s=49, 以49为中点,在49左边找3个连续奇数分别是43、45、47,在49的右边找3个连续奇数分别是51、53、55,这7个连续的奇数之和等于7的立方。
(p-s+1) + … + (p-2) + p + (p+2) + … + (p+s-1) = s*p=s^3
同理,假设s为大于1的偶数,找到第一个数p=(s*s-2s+2)/2,然后依次找出2s-1个奇数,则这2s个奇数之和等于s的立方。
p+(p+2)+...+(p+2s-2)=2sp+2s*s-2s
=s(s*s-2s+2)+2s*s-2s = s*s*s
由此证明可知check函数会正常返回结果。
问题
1. 第1个空,如果填写【sum!=k && j<k/2】,这个答案正确吗?另外,只要能设置一个能结束循环的条件,都能让程序找出正确的结果,比如【sum!=k && j<k】。但在阅卷时,答案是否正确依据的是程序的逻辑是否正确,显然,第1个答案是正确的,但第2个答案是错误的,因为它与第35行的逻辑冲突。
2. 第2个空,如果填写【sum+p<cu】对吗?从逻辑上说,答案是正确的。
3. 这道题存在的问题。
(1) 两个空的答案太相似,如果考生懂一个,另一个也懂。
(2) 35行语句无用且不完整,假使条件成立,它除了输出”error"然后返回什么呢?完整的语句应该是:
if(i>=k/2) {
printf("error!");
exit(1);
}
条件成立,直接输出“error",然后结束程序的运行。
/*-----------
【程序填空】
-------------
题目:整型数组s中有N个正整数,程序将数组按升序排列。
程序运行结果如下:
原数组为:
61 87 34 40 69 64 58 98 22 84
排序后数组为:
22 34 40 58 61 64 69 84 87 98
------------------------------
注意:在填空标志处填写答案,并删除填空标志,勿改动程序中的其他部分。
----------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#define N 10
int main()
{
int i,j,x,s[N]= {61,87,34,40,69,64,58,98,22,84};
printf("原数组为:\n" );
for(i=0; i<N; i++)
printf("%3d", s[i]);
i=N-2;
while(i>=0)
{
x=s[i];
j=i+1;
/******SPACE*********/
while(s[j]<x&& 【?】)
{
s[j-1]=s[j];
j++;
}
/*****SPACE*********/
s[【?】] =x;
i--;
}
printf("\n排序后数组为:\n" );
for(i=0; i<N; i++)
printf("%3d", s[i]);
printf("\n");
return 0;
}
答案:
=======(答案1)=======
j<N
N>j
j<=N-1
N-1>=j
=======(答案2)=======
j-1
-1+j
--j
解析:
本题采用插入排序方法对无序数进行排序,但其排序方法与平时学的方法有点不一样,差别就是平时我们把第一个元素看作是有序序列,然后从第2个元素开始到最后一个元素,依次将它们插入到有序表中。本题是假定最后一个元素是有序的,然后从倒数第二个元素开始到第一个元素,依次插入到有序表中。如果对算法熟悉,这个题不难。
问题
第1个空,如果填写【s[j+1]!=0】对否?这个答案肯定不对,原因是程序运行时系统或正常运行结束,或出现异常,完全由系统运行环境决定。因为当i的值为N-2时,31行的j被赋值为N-1,33行若s[j]<x,那么要判断s[j+1]!=0,但j+1等于N,对于数组s来说,数组越界,在以后的判断中,若x总是比已排序的数据都大,总会遇到j+1等于N,所以这个答案存在风险!在我们调试程序时,若在该数组之后正好是0时,程序运行结果正确,否则程序运行结果就是错误的。
为了验证这个答案是错的,可以再设两个数组s1[1]={1}和s2[1]={2},将其放在s数组两侧,然后运行。下面是在Dev C++中调试的结果。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#define N 10
int main()
{
int i,j,x,s1[1]={1},s[N]= {61,87,34,40,69,64,58,98,22,84},s2[1]={2};
printf("原数组为:\n" );
for(i=0; i<N; i++)
printf("%3d", s[i]);
i=N-2;
while(i>=0)
{
x=s[i];
j=i+1;
/******SPACE*********/
while(s[j]<x&& s[j+1]!=0)
{
s[j-1]=s[j];
j++;
}
/*****SPACE*********/
s[j-1] =x;
i--;
}
printf("\n排序后数组为:\n" );
for(i=0; i<N; i++)
printf("%3d", s[i]);
printf("\n");
return 0;
}
程序运行结果如下:
显然,程序运行结果是错的。