请改正程序中的错误后调试程序,并指出程序运行的结果。
longfun(longn,intr)
{longy=0,t=1;
while(n)
{y+=t*(n%r);
t*=10;
n%=r;/*本行语句有错误*/
}
returnt;/*本行语句有错误*/
}
main()
{longa=197;intr=7;
printf("%ld",fun(a,r));
}
参考答案:
n%=r;改为n/=r;
returnt;改为returny;
输出结果:
401
解题技巧:
A.十进制整数化为r进制整数的基本方法是除r取余法。
按照这种思路去阅读代码,很容易认清各语句的作用,从而纠正错误。
B.根据题目叙述,结合main函数的代码,程序就是输出197的7进制整数。
直接利用除7取余法即可用笔算得到结果。
或者,利用Windows的计算器得到结果。
图4:
EXCEL求解图示
EXCEL解法
(1)在A1单元格输入十进制整数,在B1单元格输入R的值。
如图4所示。
(2)在A2输入公式:
=INT(A1/$B$1)
(3)在B2输入公式:
=MOD(A1,$B$1)
(4)选择A2至B2,向下拖填充柄,至A列出现0为此。
此时,由B列由下向上至B2,即为A1单元格整数化为R进制数。
2、相差为2的两个素数称为双胞胎数。
下列程序用于求[200,1000]上有多少对双胞胎数。
改正程序中的错误后调试程序,并指出程序运行的结果。
intisZ(intx)
{intk=2;
while(k*k<=x)
if(x%k==0)continue;elsek++;/*本行语句有错误*/
return(x>1)&&(k*k>x);
}
main()
{intx,n=0;
for(x=203;x<997;x+=2)
if(isZ(x)||isZ(x+2))n++;/*本行语句有错误*/
printf("%d",n);
}
参考答案:
if(x%k==0)continue;elsek++;改为if(x%k==0)break;elsek++;
if(isZ(x)||isZ(x+2))n++;改为if(isZ(x)&&isZ(x+2))n++;
输出结果:
20
特别提示:
return(x>1)&&(k*k>x);不能修改为returnk*k>x;否则1会认为是素数。
而1既不是素数,也不是合数。
解题技巧:
根据题意,很容易分析出主函数中的if语句是用于判断x和x+2是否为素数的。
因此推断出,isZ函数的作用是判断素数。
而判断一个整数x是否为素数的基本方法就是在[2,sqrt(x)]上搜索x的约数。
按照这一思路分析代码,即可纠正错误。
3、下列程序用于计算四位数的奇数中,各位数字之积是60的正整数倍的数的和。
改正程序中的错误后调试程序,并指出程序运行的结果。
main()
{intk,t,s=0;/*本行语句有错误*/
for(k=1001;k<10000;k+=2)
{t=(k/1000)*(k/100%10)*(k/10%10)*(k%10);
if(t%60==0)s+=t;/*本行语句有错误*/
}
printf("%ld",s);
}
参考答案:
intk,t,s=0;改为intk,t;longs=0;
if(t%60==0)s+=t;改为if(t&&t%60==0)s+=k;
输出结果:
3456254
解题技巧:
A.定义变量的语句出现错误,无非两种可能:
Ø变量初值错误或未赋初值。
一般而言,用于计数、求和的变量初值为0。
但要注意程序的处理方法,计数变量的初值也可能是1、求和变量的初值也可能是满足条件的第一个数据。
Ø变量类型错误。
这主要是由于数据超过了变量的赋值范围。
建议对整数类计数或求和问题,将变量类型均定义为long类型。
本题中,从printf("%ld",s)也可看出变量s为long类型。
B.本题中的第二个错误很容易忽视:
审题不清。
题目要求的是60的正整数倍,因此,还必须有条件t>0。
4、下列程序用于计算满足条件的四位数ABCD的个数:
是8的倍数;A+B=B+C。
改正程序中的错误后调试程序,并指出程序运行的结果。
main()
{intk,n;/*本行语句有错误*/
for(k=1000;k<10000;k++)/*本行语句有错误*/
if(k/1000==k/10%10)n++;
printf("%d",n);
}
参考答案:
intk,n;改为intk,n=0;
for(k=1000;k<10000;k++)改为for(k=1000;k<10000;k+=8)
输出结果:
110
解题技巧:
A.正如上题分析,变量定义的语句出错,只有两个可能。
B.根据题意,搜索的整数必须满足三个条件:
其一,是四位正整数;其二,是8的倍数;其三,A=C。
以此为线索,易知,第二个条件未在代码中体现。
考虑到1000是8的倍数,因此,循环变量的增量(也叫步长)修改为8即可。
第三部分:
程序填空题典型范例
1、下列程序可输出1000~9999之间所有四位数的个数:
它是一个完全平方数,其左两位数字之和为10,右两位数字之积为18。
请在下划线上填写适当的语句后运行程序,并给出程序运行的结果。
main()
{intk,x,n=0;
for(k=32;k<100;k++)
{x=___________;
if(x/1000+(x/100%10)==10)
if(__________________)n++;
}
printf("%d",n);
}
参考答案:
k*k(x/10%10)*(x%10)==18
程序运行结果:
1
解题技巧:
A.根据题意(读懂、认准题目的已知条件、需要得到什么结果?
这是理解代码的关键!
),四位数必须是一个完全平方数,但代码中并未对四位数进行循环搜索,而是由k在区间[32,100)上穷举。
其意图是什么呢?
由于312=961是三位数,而322=1024是四位数(四位数中最小的完全平方数!
),1002是五位数!
发现了这一特点,思路便变得清晰:
由k*k得到平方数(当然是四位数),可有效避免平方数的判断,简化代码。
故第一空应填写:
k*k
B.if语句是判断平方数x是否满足题设条件。
代码已经给出了一个条件x/1000+(x/100%10)==10,也就是千位数字与百位数字(四位数的左两位)之和是否为10。
第二个条件自然是右两位数字之积是否为18:
(x/10%10)*(x%10)==18。
2、斐波那契数列的前二项均为1,从第三项起,每项均为前两项的和。
下列程序求10000000内最大的斐波那契数。
请在下划线上填写适当的语句后运行程序,并给出程序运行的结果。
main()
{longa=1,b=1;
while(_______________)
b+=a,__________________;
printf("%ld",a);
}
参考答案:
b<=10000000a=b-a
程序运行结果:
9227465
解题技巧:
A.题目是求10000000内最大的斐波那契数。
而代码中的输出语句是printf("%ld",a);->可见循环条件是b<=10000000。
为什么不是a<=10000000?
因为如果是这样,则终止循环时,必有a>10000000,不满足题的要求。
注意:
a是b的前项。
B.从代码来看,其算法的基本思路是:
不用第三个变量,直接根据当前项b及前项a计算出下一项及其前项。
因此,第二个空应填a=b-a。
但是,你想不到怎么办?
改代码!
用你熟悉的方法,增加第三个变量t=a+b,a=b,b=t!
3、以下程序求最大的三位数:
其每位数字互异且立方和等于该数。
请在下划线上填写适当的语句后运行程序,并给出程序运行的结果。
main()
{intk,a,b,c;
for(k=999;k>=100;k--)
{a=k/100;___________;c=k%10;
if(a!
=b&&a!
=c&&b!
=c)
if(a*a*a+b*b*b+c*c*c==k)___________;
}
printf("%d",k);
}
参考答案:
break
程序运行结果:
407
解题技巧:
A.既然是求最大的三位数,当然是从大到小搜索,找到满足条件的即结束。
因此,第二个空该填break。
B.条件是各位数字互异且立方和等于数本身。
因此,需求出各位数字。
代码中已求出百位数字a和个位数字c,故第一个空中应求十位数字b,故应填b=k/10%10。
4、仔细阅读以下程序,根据程序实现的功能,在下划线上填写适当的语句后运行程序,并给出程序运行的结果。
intisrep(longn)/*判断整数各位数字是否有重复*/
{intk;longm;
while(n)
{k=n%10;m=n/10;/*取n的个位与其他位比较*/
while(m)
if(__________)return1;elsem/=10;
_____________
}
return0;
}
main()
{longx=3456123;
printf("%d",isrep(x));
}
参考答案:
k==m%10n/=10;
程序运行结果:
1
解题技巧:
从代码注释可得到算法的基本思路:
A.取n的个位数字k:
k=n%10;m=n/10;
B.取n的其他位组成的数:
m=n/10;
C.判断k是否在m中出现:
(采取删除个位法)
a.取m的个位与k比较:
如果相等,返回值1,结束。
b.删除m的个位:
m/=10。
c.如果m=0,转D,否则转a。
D.删除n的个位:
n/=10
E.如果n=0,返回值0,结束。
否则转A。
第四部分:
程序设计题典型范例
1、编程求解有多少个这样的四位正整数:
其各位数字的和是3的倍数含数字5。
main()
{intk,m,n=0;
for(k=1005;k<9975;k+=3)
{m=k;
while(m)if(m%10==5)break;elsem/=10;
if(m)n++;
}
printf("%d",n);
}
参考答案:
1059
解题技巧:
如果你无法完成代码,不妨用数学方法解决!
当然,也可利用EXCEL求解:
(1)先生成3的倍数:
在A1输入1005、A2输入1008,再选择A1和A2,向下拖填充柄至得到9975;
(2)再从3的倍数中找出含数字5的数:
在B1单元格输入公式:
=IF(FIND("5",A1&"5")<5,1,"")
注意:
公式=IF(FIND("5",A1),1,"")也可实现查找,但是,由于FIND函数如果未找到串,返回值为#VALUE!
,不方便SUM函数的处理。
(3)选择B1,向下拖填充柄至最后行;
(4)在C1输入:
=SUM(B:
B)。
这时C1显示值为1059,即本题答案。
2、求[2,1000]上所有同构数之和。
如果n2的低位是n,则称正整数n为同构数。
分析:
设k位数为p,则k是同构数当且仅当k2-k能被10p整除。
求解的基本思路是:
(1)k=2,s=0。
对k进行穷举搜索。
和值s初值为0。
(2)根据k的位数p确定t=10p
A.t=1,n=k
B.while(n)t*=10,n/=10
(3)如果k2-k能被t整除,则s+=k
(4)k++。
如果k>1000则输出和值s,程序结束。
否则转
(2)
main()
{ints=0,t,n;longk;
for(k=2;k<=1000;k++)
{t=1;n=k;
while(n)t*=10,n/=10;
图5:
EXCEL求解图示
if((k*k-k)%t==0)s+=k;
}
printf("%d",s);
}
参考答案:
1113
EXCEL解法
(1)在A列输入2,3,...,999。
如图5所示。
(2)在B2输入公式:
=A2*A2-A2
(3)在C2输入公式:
=(A2>99)+(A2>9)+1
(4)在D2输入公式:
=IF(MOD(B2,10^C2)=0,A2,"")
(5)选择B2至D2,向下拖填充柄至最后行;
(6)在E2输入公式:
=SUM(D:
D)
此时E2显示1113,即本题答案。
3、某些分数的分子分母都是二位正整数的真分数,如果将分子的两位数字相加作分子,分母两位数字相加作分母,得到的分数值不变。
求这些分数的分子与分母的总和。
分析:
设分子为x,分母为y,则x可先对x在区间[10,99)上穷举,对每一个x,再在区间[x+1,99]上搜索匹配条件的y。
main()
{intx,y,s=0;
for(x=10;x<99;x++)
for(y=x+1;y<100;y++)
if(y*(x/10%10+x%10)==x*(y/10%10+y%10))s+=x+y;
printf("%d",s);
}/*x/y=m/n即xn=ym,转化以避免分数运算带来的误差。
*/
参考答案:
10134
EXCEL解法
图6:
EXCEL求解图示
(1)在A列输入分子10-98、第一行输入分母11-99,如图6所示;
(2)在B2单元格输入公式:
=IF(AND($A2
公式说明:
AND包括二个条件:
$A2
表示分子小于分母;
(INT($A2/10)+MOD($A2,10))*B$1=(INT(B$1/10)+MOD(B$1,10))*$A2),$A2+B$1,""):
表示分子的两个数字相加后,与分母两个数字之和的商不变。
(3)选择B2,向右拖填充柄至CL2;
(4)选择B2至CL2,向下拖填充柄至第90行;
(5)在CM2输入公式:
=SUM(B2:
CL90)
此时CM2单元格显示10134,即本题答案。
4、正整数A、B的最大公约数为10,最小公倍数为100,且A
分析:
由题意,可设A=10M,B=10N,M、N互质。
则有:
AB=1000(数学结论:
两个整数之积等于其最大公约数与最小公倍数之积),即:
MN=10。
故(M,N)=(1,10)或(2,5)。
以上是数学解法。
编程求解则可通过以下思路实现:
(1)A=10(A是10的倍数,从10开始搜索求解)
(2)求B:
如果1000%A=0则转(3),否则转(6)
(3)B=1000/A(利用上面的数学结论)。
若A>=B则结束。
(4)求A、B的最大公约数F
(5)如果F=10,则得到一组解,解数N++
(6)A+=10(搜索下一个可能的解)
(7)如果A>100则结束。
否则转
(2)
main()
{inta=10,b,n=0,c,d,r;
while(a<=100)
{if(1000%a==0)
{b=1000/a;
if(a>=b)break;
c=b;d=a;
while(d)
r=c%d,c=d,d=r;
if(c==10)n++;
}
a+=10;
}
printf("%d",n);}
第五部分:
程序题主要考点
【考点一】在一定范围内求满足条件的整数个数(或求最大最小值、求和)。
【求解方法】利用循环,在指定范围内搜索求解。
【易错点】
统计整数个数或求和的变量未赋初值。
一般应赋初值0。
求和时变量类型错误,造成数据溢出。
建议用于整数求和的变量均定义为long类型。
数据过大时,用double类型。
比较两个数是否相等的运算符是"=="而不是"="。
调用数学函数未用预处理命令:
#include"math.h"
【程序示例】
1、编写程序,计算0~50范围内有多少个数,其每位数字之积小于每位数字和。
分析:
一位数显然不满足条件。
求解思路是:
(1)k=10,n=0(k作循环变量,n统计满足条件的数据个数)
(2)取k的十位数字a和个位数字b:
a=k/10,b=k%10
(3)如果ab(4)k++
(5)如果k>50则输出n的值,程序结束。
否则转
(2)
参考代码(n=17):
main()
{intk,a,b,n=0;
for(k=10;k<=50;k++)
{a=k/10,b=k%10;
if(a*b}
printf("%d",n);
}
显然,该题用数学方法也很容易得到结果。
图7:
EXCEL求解图示
借助EXCEL,求解更简单。
如图7,基本操作步骤:
(1)在A1、A2单元格内分别输入10、20
(2)选择A1、A2两个单元格,向下拖动填充柄,拖到第50行时松开鼠标。
这时,A列有数据10-50。
(在EXCEL中,输入等差数列的前二项后,选择其单元格,拖其填充柄即可得到等差序列。
)
(3)在B1单元格输入公式(取十位数字):
=int(A1/10)
(4)在C1单元格输入公式(取个位数字):
=mod(A1,10)
(5)在D1单元格输入公式:
=if(B1*C1(6)选择B1、C1和D1单元格,拖动填充柄至第50行。
(7)在E1单元格输入公式:
=sum(D1:
D50)
(8)这时E1单元格显示数值17。
这就是问题的答案。
2、一个正整数如果等于其所有因子之和,则称该数为完数。
求[6,10000]上完