关于数字黑洞495和6174 卡布列克运算(初一的作业)的验证?

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-06-30
验证卡布列克运算

var n,t:integer;

procedure fournum(f:integer;var f1,f2,f3,f4:integer); {取得四位字各位数字的过程}
var n1,n2,n3,n4:integer;
begin
n1:=f div 1000;
n2:=(f-n1*1000) div 100;
n3:=(f-n1*1000-n2*100) div 10;
n4:=f mod 10;
f1:=n1;f2:=n2;f3:=n3;f4:=n4;
end;

function pdsame(s:integer):boolean; {判断该数是否不全相同的函数}
var p:array[1..4] of integer;
q,r:integer;
begin
fournum(s,p[1],p[2],p[3],p[4]);
pdsame:=true;
for q:=1 to 3 do begin
for r:=q+1 to 4 do begin
if p[q]p[r] then pdsame:=false;
end;
end;
end;

procedure kblk(m:integer); {递归过程,卡布列克运算}
var num:array[1..4] of integer;
i,j,k,x,y:integer;
begin
if m=6174 then begin
writeln('total times: ',t);
end else begin
fournum(m,num[1],num[2],num[3],num[4]);
for i:=1 to 3 do begin
for j:=i+1 to 4 do begin
if num[i]<num[j] then begin
k:=num[i];
num[i]:=num[j];
num[j]:=k;
end;
end;
end;
x:=num[1]*1000+num[2]*100+num[3]*10+num[4];
y:=num[4]*1000+num[3]*100+num[2]*10+num[1];
writeln(x,' - ',y,' = ',x-y);
t:=t+1;
kblk(x-y);
end;
end;

begin {主程序}
readln(n);
if (n9999) or (pdsame(n)) then
writeln('wrong input!') else begin
t:=0;
kblk(n);
end;
end.

#include#include#includevoid paixu(int *num);int maxium(int *num);int minium(int *num);int main(){ int num[4]; int number,flag=0; int i,j; while(flag==0) { printf("请输入数字:"); scanf("%d",&number); fflush(stdin); for(i=0;i<4;i++) num[i]=(int)(number/pow(10.0,(double)i))%10; for(i=0,flag=1;i<3;i++) { for(j=i+1;j<4;j++) if(num[i]==num[j]) { flag=0; break; } if(flag==0) break; } } paixu(num); number=maxium(num)-minium(num); printf("%d-%d=%d
",maxium(num),minium(num),number); while(number!=6174) { for(i=0;i<4;i++) num[i]=(int)(number/pow(10.0,(double)i))%10; paixu(num); number=maxium(num)-minium(num); printf("%d-%d=%d
",maxium(num),minium(num),number); }}void paixu(int *num){ int i,j,temp; for(i=0;i<4;i++) for(j=0;j<3-i;j++) if(num[j]<num[j+1]) { temp=num[j]; num[j]=num[j+1]; num[j+1]=temp; }}int maxium(int *num){ int max=0,i; for(i=0;i<4;i++) max=max+(int)(num[i]*pow(10.0,3-i)); return max;}int minium(int *num){ int min=0,i; for(i=0;i<4;i++) min=min+(int)(num[i]*pow(10.0,i)); return min;}

设M是一个四位数而且四个数字不全相同,把M的数字按递减的次序排列,
记作M(减);
然后再把M中的数字按递增次序排列,记作M增,记差M(减)-M(增)=D1,从M到D1是经过上述步骤得来的,我们把它看作一种变换,从M变换到D1记作:T(M)= D1把D1视作M一样,按上述法则做减法得到D2 ,也可看作是一种变换,把D1变换成D2,
记作:T(D1)= D2
同样D2可以变换为D3;D3变换为D4……,既T(D2)= D3, T(D3)= D4……
现在我们要证明,至多是重复7次变换就得D7=6174。
证:四位数总共有104=10000个,其中除去四个数字全相同的,余下104-10=9990个数字不全相同.我们首先证明,变换T把这9990个数只变换成54个不同的四位数.
设a、b、c、d是M的数字,并令:
a≥b≥c≥d
因为它们不全相等,上式中的等号不能同时成立.我们计算T(M)
M(减)=1000a+100b+10c+d
M(增)=1000d+100c+10b+a
T(M)= D1= M(减)-M(增)=1000(a-d)+100(b-c)+10(c-b)+d-a=999(a-d)+90(b-c)
我们注意到T(M)仅依赖于(a-d)与(b-c),因为数字a,b,c,d不全相等,因此由a≥b≥c≥d可推出;a-d>0而b-c≥0.
此外b、c在a与d之间,所以a-d≥b-c,这就意味着a-d可以取1,2,…,9九个值,并且如果它取这个集合的某个值n,b-c只能取小于n的值,至多取n.
例如,若a-d=1,则b-c只能在0与1中选到,在这种情况下,T(M)只能取值:
999×(1)+90×(0)=0999
999×(1)+90×(1)=1089
类似地,若a-d=2, T(M)只能取对应于b-c=0,1,2的三个值.把a-d=1,a-d=2,…,a-d=9的情况下b-c所可能取值的个数加起来,我们就得到2+3+4+…+10=54
这就是T(M)所可能取的值的个数.在54个可能值中,又有一部分是数码相同仅仅是数位不同的值,这些数值再变换T(M)中都对应相同的值(数学上称这两个数等价),剔除等价的因数,在T(M)的54个可能值中,只有30个是不等价的,它们是:
9990,9981,9972,9963,9954,9810,9711,9621,9531,9441,8820,8730,8721,8640,8622,8550,
8532,8442,7731,7641,7632,7551,7533,7443,6642,6552,6543,5553,5544.
对于这30个数逐个地用上述法则把它换成最大与最小数的差,至多6步就出现6174这个数.证毕.参考资料:http://baike.baidu.com/view/406175.html?wtp=tt

黑洞数也称为陷阱数,又称“Kaprekar问题”,是一类具有奇特转换特性的数。
任何一个数字不全相同的三位数,经有限次“重排求差”操作,总会得到495.最后所得的495即为三位黑洞数。所谓“重排求差”操作即组成该数的数字重排后的最大数减去重排后的最小数。(6174为四位黑洞数)
例如,对三位数207:
第1次重排求差得:720-027=693;
第2次重排求差得:963-369=594;
第3次重排求差得:954
以后会停留在495这一-459=495;黑洞数。
如果三位数的3个数字全同,一次转换后即为0.因而,可把0与495一并作为判断条件。试求出任意输入三位数重排求差的过程。