博文

27.自守数(2005-09-10 15:12:00)

摘要:27.自守数 自守数是指一个数的平方的尾数等于该数自身的自然数。例如: 252=625 762=5776 93762=87909376 请求出200000以内的自守数 *题目分析与算法设计 若采用“求出一个数的平方后再截取最后相应位数”的方法显然是不可取的,因为计算机无法表示过大的整数。 分析手工方式下整数平方(乘法)的计算过程,以376为例: 376 被乘数 X 376 乘数 ---------- 2256 第一个部分积=被乘数*乘数的倒数第一位 2632 第二个部分积=被乘数*乘数的倒数第二位 1128 第三个部分积=被乘数*乘数的倒数第三位 ---------- 141376 积 本问题所关心的是积的最后三位。分析产生积的后三位的过程,可以看出,在每一次的部分积中,并不是它的每一位都会对积的后三位产生影响。总结规律可以得到:在三位数乘法中,对积的后三位产生影响的部分积分别为: 第一个部分积中:被乘数最后三位*乘数的倒数第一位 第二个部分积中:被乘数最后二位*乘数的倒数第二位 第三个部分积中:被乘数最后一位*乘数的倒数第三位 将以上的部分积的后三位求和后截取后三位就是三位数乘积的后三位。这样的规律可以推广到同样问题的不同位数乘积。 按照手工计算的过程可以设计算法编写程序。 *程序说明与注释 #include<stdio.h> void main() { long mul,number,k,ll,kk; printf("It exists following automorphic nmbers small than 200000:\n"); for(number=0;number<200000;number++) { for(mul=number,k=1;(mul/=10)>0;k*=10); /*由number的位数确定截取数字进行乘法时的系数k*/ kk=k*10; /*kk为截取部分积时的系数*/ mul=0; /*积的最后n位*/ ll=10; /*ll为截取乘数相应位时的系数*/ while(k>0) { mul=(mul+(number%(k*10))*(number%ll-number%(ll/10)))%kk; /*(部分积+截取被乘数的后N位*截取乘数的第M位),%kk再截取部分积*/ k/=......

阅读全文(3574) | 评论:0

26.亲密数(2005-09-10 15:12:00)

摘要:26.亲密数 如果整数A的全部因子(包括1,不包括A本身)之和等于B;且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。求3000以内的全部亲密数。 *题目分析与算法设计 按照亲密数定义,要判断数a是否有亲密数,只要计算出a的全部因子的累加和为b,再计算b的全部因子的累加和为n,若n等于a则可判定a和b是亲密数。计算数a的各因子的算法: 用a依次对i(i=1~a/2)进行模运算,若模运算结果等于0,则i为a的一个因子;否则i就不是a的因子。 *程序说明与注释 #include<stdio.h> void main() { int a,i,b,n; printf("There are following friendly--numbers pair smaller than 3000:\n"); for(a=1;a<3000;a++) /*穷举1000以内的全部整数*/ { for(b=0,i=1;i<=a/2;i++) /*计算数a的各因子,各因子之和存放于b*/ if(!(a%i))b+=i; /*计算b的各因子,各因子之和存于n*/ for(n=0,i=1;i<=b/2;i++) if(!(b%i))n+=i; if(n==a&&a<b) printf("%4d..%4d ",a,b); /*若n=a,则a和b是一对亲密数,输出*/ } } *运行结果 There are following friendly--numbers pair smaller than 3000: 220.. 284 1184.. 1210 2620.. 2924......

阅读全文(3288) | 评论:0

24.完全数(2005-09-10 15:12:00)

摘要:24.完全数 如果一个数恰好等于它的因子之和,则称该数为“完全数”。 *题目分析与算法设计 根据完全数的定义,先计算所选取的整数a(a的取值1~1000)的因子,将各因子累加于m,若m等于a,则可确认a为完全数。 *程序说明与注释 #include<stdio.h> void main() { int a,i,m; printf("There are following perfect numbers smaller than 1000:\n"); for(a=1;a<1000;a++) /*循环控制选取1~1000中的各数进行判断*/ { for(m=0,i=1;i<=a/2;i++) /*计算a的因子,并将各因子之和m=a,则a是完全数输出*/ if(!(a%i))m+=i; if(m==a) printf("%4d ",a); } printf("\n"); } *运行结果 TThere are following perfect numbers smaller than 1000: 6 28 496 ......

阅读全文(3111) | 评论:0

23.阿姆斯特朗数(2005-09-10 15:09:00)

摘要:23.阿姆斯特朗数 如果一个正整数等于其各个数字的立方和,则称该数为阿姆斯特朗数(亦称为自恋性数)。 如 407=43+03+73就是一个阿姆斯特朗数。试编程求1000以内的所有阿姆斯特朗数。 *题目分析与算法设计 可采用穷举法,依次取1000以内的各数(设为i),将i的各位数字分解后,据阿姆斯特朗数的性质进行计算和判断。 *程序说明与注释 #include<stdio.h> void main() { int i,t,k,a[3]; printf("There are follwing Armstrong number smaller than 1000:\n"); for(i=2;i<1000;i++) /*穷举要判定的数i的取值范围2~1000*/ { for(t=0,k=1000;k>=10;t++) /*截取整数i的各位(从高向低位)*/ { a[t]=(i%k)/(k/10); /*分别赋于a[0]~a[2}*/ k/=10; } if(a[0]*a[0]*a[0]+a[1]*a[1]*a[1]+a[2]*a[2]*a[2]==i) /*判断i是否为阿姆斯特朗数*/ printf("%5d",i); /*若满足条件,则输出*/ } printf("\n"); } *运行结果 There are following Armstrong number smaller than 1000: 153 370 371 407 ......

阅读全文(5078) | 评论:1

22.求车速(2005-09-10 15:12:00)

摘要:22.求车速 一辆以固定速度行驶的汽车,司机在上午10点看到里程表上的读数是一个对称数(即这个数从左向右读和从右向左读是完全一样的),为95859。两小时后里程表上出现了一个新的对称数。问该车的速度是多少?新的对称数是多少? *题目分析与算法设计 根据题意,设所求对称数为i,其初值为95589,对其依次递增取值,将i值的每一位分解后与其对称位置上的数进行比较,若每个对称位置上的数皆相等,则可判定i即为所求的对称数。 *程序说明与注释 #include<stdio.h> void main() { int t,a[5]; /*数组a存放分解的数字位*/ long int k,i; for(i=95860;;i++) /*以95860为初值,循环试探*/ { for(t=0,k=100000;k>=10;t++) /*从高到低分解所取i值的每位数*/ { /* 字,依次存放于a[0]~a[5]中*/ a[t]=(i%k)/(k/10); k/=10; } if((a[0]==a[4])&&(a[1]==a[3])) { printf("The new symmetrical number kelometers is:%d%d%d%d%d\n", a[0],a[1],a[2],a[3],a[4]); printf("The velocity of the car is: %.2f\n",(i-95859)/2.0); break; } } } *运行结果 The new symmetrical number kelometers is:95959. The velocity of the car is:50.00 *思考题 将一个数的数码倒过来所得到的新数叫原数的反序数。如果一个数等于它的反序数,则称它为对称数。求不超过1993的最大的二进制的对称数。 ......

阅读全文(3239) | 评论:0

21.4位反序数(2005-09-10 15:12:00)

摘要:21.4位反序数 设N是一个四位数,它的9倍恰好是其反序数,求N。反序数就是将整数的数字倒过来形成的整数。例如:1234的反序数是4321。 *题目分析与算法设计 可设整数N的千、百、十、个位为i、j、k、l,其取值均为0~9,则满足关系式: (i*103+j*102+10*k+l)*9=(l*103+k*102+10*j+i) 的i、j、k、l即构成N。 *程序说明与注释 #include<stdio.h> void main() { int i; for(i=1002;i<1111;i++) /*穷举四位数可能的值*/ if(i%10*1000+i/10%10*100+i/100%10*10+i/1000==i*9) /*判断反序数是否是原整数的9倍*/ printf("The number satisfied stats condition is: %d\n",i); /*若是则输出*/ } *运行结果 The number satisfied states condition is:1089......

阅读全文(3672) | 评论:0

20.一个奇异的三位数(2005-09-10 15:12:00)

摘要:20.一个奇异的三位数 一个自然数的七进制表达式是一个三位数,而这个自然数的九进制表示也是一个三位数,且这两个三位数的数码正好相反,求这个三位数。 *题目分析与算法设计 根据题意可知,七进制和九进制表示的这全自然数的每一位一定小于7,可设其七进制数形式为kji(i、j、k的取值分别为1~6),然后设其九进制表示形式为ijk。 *程序说明与注释 #include<stdio.h> void main() { int i,j,k; for(i=1;i<7;i++) for(j=0;j<7;j++) for(k=1;k<7;k++) if(i*9*9+j*9+k==i+j*7+k*7*7) { printf("The special number with 3 digits is:"); printf("%d%d%d(7)=%d%d%d(9)=%d(10)\n",k,j,i,i,j,k,i*9*9+j*9+k); } } *运行结果 The special number with 3 digits is:503(7)=305(9)=248(10) ......

阅读全文(2865) | 评论:0

19. 8 除不尽的数(2005-09-10 15:09:00)

摘要:19. 8 除不尽的数 一个自然数被8除余1,所得的商被8除也余1,再将第二次的商被8除后余7,最后得到一个商为a。又知这个自然数被17除余4,所得的商被17除余15,最后得到一个商是a的2倍。求这个自然数。 *题目分析与算法设计 根据题意,可设最后的商为i(i从0开始取值),用逆推法可以列出关系式: (((i*8+7)*8)+1)*8+1=((2*i*17)+15)*18+4 再用试探法求出商i的值。 *程序说明与注释 #include<stdio.h> void main() { int i; for(i=0;;i++) /*试探商的值*/ if(((i*8+7)*8+1)*8+1==(34*i+15)*17+4) { /*逆推判断所取得的当前i值是否满足关系式*/ /*若满足则输出结果*/ printf("The required number is: %d\n",(34*i+15)*17+4); break; /*退出循环*/ } } *运行结果 The required number is:1993 ......

阅读全文(2894) | 评论:0

18.有限5位数(2005-09-10 15:09:00)

摘要:18.有限5位数 个位数为6且能被3整除的五位数共有多少? *题目分析与算法设计 根据题意可知,满足条件的五位数的选择范围是10006、10016。。。99996。可设基础数i=1000,通过计算i*10+6即可得到欲选的数(i的变化范围是1000~999),再判断该数能否被3整除。 *程序说明与注释 #include<stdio.h> void main() { long int i; int count=0; /*count:统计满足条件的五位数的个数*/ for(i=1000;i<9999;i++) if(!((i*10+6)%3)) /*判断所选的数能否被3整除*/ count++; /*若满足条件则计数*/ printf("count=%d\n",count); } *运行结果 count=2999 *思考题 求100到1000之间有多少个其数字之和为5的整数。 (答案:104,113,122,131,140,203,212,221,230,302,311,320,401,410,500) ......

阅读全文(3222) | 评论:0

17.平分七筐鱼(2005-09-10 15:09:00)

摘要:17.平分七筐鱼 甲、乙、丙三位鱼夫出海打鱼,他们随船带了21只箩筐。当晚返航时,他们发现有七筐装满了鱼,还有七筐装了半筐鱼,另外七筐则是空的,由于他们没有秤,只好通过目测认为七个满筐鱼的重量是相等的,7个半筐鱼的重量是相等的。在不将鱼倒出来的前提下,怎样将鱼和筐平分为三份? *问题分析与算法设计 根据题意可以知道:每个人应分得七个箩筐,其中有3.5筐鱼。采用一个3*3的数组a来表示三个人分到的东西。其中每个人对应数组a的一行,数组的第0列放分到的鱼的整筐数,数组的第1列放分到的半筐数,数组的第2列放分到的空筐数。由题目可以推出: 。数组的每行或每列的元素之和都为7; 。对数组的行来说,满筐数加半筐数=3.5; 。每个人所得的满筐数不能超过3筐; 。每个人都必须至少有1 个半筐,且半筐数一定为奇数 对于找到的某种分鱼方案,三个人谁拿哪一份都是相同的,为了避免出现重复的分配方案,可以规定:第二个人的满筐数等于第一个人的满筐数;第二个人的半筐数大于等于第一个人的半筐数。 *程序与程序注释 #include<stdio.h> int a[3][3],count; void main() { int i,j,k,m,n,flag; printf("It exists possible distribtion plans:\n"); for(i=0;i<=3;i++) /*试探第一个人满筐a[0][0]的值,满筐数不能>3*/ { a[0][0]=i; for(j=i;j<=7-i&&j<=3;j++) /*试探第二个人满筐a[1][0]的值,满筐数不能>3*/ { a[1][0]=j; if((a[2][0]=7-j-a[0][0])>3)continue; /*第三个人满筐数不能>3*/ if(a[2][0]<a[1][0])break; /*要求后一个人分的满筐数>=前一个人,以排除重复情况*/ for(k=1;k<=5;k+=2) /*试探半筐a[0][1]的值,半筐数为奇数*/ { a[0][1]=k; for(m=1;m<7-k;m+=2) /*试探 半筐a[1][1]的值,半筐数为奇数*/ { a[1][1]=m; a[2][1]=7-k-m; fo......

阅读全文(3633) | 评论:3