查看文章 |
卡普雷卡尔--数学黑洞数 (C++演示)[原创]
2009-06-02 11:19
题目:“数学黑洞”:任意一个4位自然数,将组成该数的各位数字重新排列,形成一个最大数和一个最小数,之后两数相减,其差仍为一个自然数。重复进行上述运算,最终会出现一个神秘的数,请编程输出这个神秘的数。 介绍: 取任何一个4位数(4个数字均为同一个数字的例外),将组成该数的4个数字重新组合成可能的最 大数和可能的最小数,再将两者的差求出来;对此差值重复同样的过程(例如:开始时取数8028,最大的重新组合数为8820,最小的为0288,二者的差 8532。重复上述过程得出8532-2358=6174),最后总是达到卡普雷卡尔黑洞:6174。称之“黑洞”是指再继续运算,都重复这个数,“逃” 不出去。把以上计算过程称为卡普雷卡尔运算,这个现象称归敛,其结果6174称归敛结果。 一, 任意N位数都会类似4位数那样归敛(1、2位数无意义) . 3位数归敛到唯一一个数495; 4位数归敛到唯一一个数6174; 7位数归敛到唯一一个数组( 8个7位数组成的循环数组、称归敛组);其它每个位数的数归敛结果分别有若干个,归敛数和归敛组兼而有之(如14位数共有9×10的 13次方个数的归敛结果有6个归敛数,21个归敛组). 一旦进入归敛结果,继续卡普雷卡尔运算就在归敛结果反复循环,再也“逃”不出去。 归敛组中各数可以按递进顺序交换位置 (如a → b → c 或 b → c → a 或c → a → b) 归敛结果可以不经过卡普雷卡尔运算就能从得出. 某个既定位数的数,它的归敛结果的个数是有限的,也是确定的. 以下是我实现演示的代码 //Copyleft By Tianyi 2009-6-1 #include<iostream> #include<time.h> using namespace std; int number(int number); int blackHoleNumber(int number); int getNumber(int number) //求出最大组合数于最小组合数的差值 { static counter = 0; int value; int i = 0,j,temp; int maxNumber = 1000,minNumber = 1000; int digi[4]; while( number != 0 ) { digi[i] = number % 10; number = number / 10; i++; } //将各个数位存入数组digi[]中 for ( j = 0; j < 5; j++ ) { for ( i = 0; i < 5 - j; i++) { if ( digi[i] > digi[i+1] ) { temp = digi [i]; digi[i] = digi[i+1]; digi[i+1] = temp; } } } //对数位冒泡排序 minNumber = digi[0]*1000 + digi[1]*100 + digi[2]*10 + digi[3] ; maxNumber = digi[3]*1000 + digi[2]*100 + digi[1]*10 + digi[0] ; value = maxNumber - minNumber; if (counter % 2 == 0) { cout << "第" << (counter + 2)/2 << "次计算:\n"; cout << "最大数为: " << maxNumber << "\n最小数为:" << minNumber << endl; cout << "差值为: " << value << endl; cout << "=======================" << endl; }//输出结果 ++counter; return value; } int blackHoleNumber(int number) //求黑洞数函数 { do { number = getNumber(number); } while(number != getNumber(number));//当得到的差值和下一步求的的差值相等时,返回该数 return number; } int main() { srand((unsigned)time(NULL)); //时钟振荡产生随机数 int number = rand() % 10000; cout << "产生的随机数为: "<< number << endl; int value = blackHoleNumber(number); cout << "黑洞数为: " << value << endl; return 0; } |
最近读者: