#include <stdio.h>
long power(long y);
int main(void)
{
long long first, second, number, kaprekar;
int exponent;
int helper;
printf("Let's see all n digits number Kaprekar number\n");
scanf("%d", &exponent);
helper = exponent / 2;
printf("Here are Kaprekar numbers\n");
for (number = power(exponent - 1); number <= (power(exponent) - 1); number++)
{
first = number / (power(helper));
second = number - (first*(power(helper)));
if ((first + second)*(first + second) == number)
printf("%lld\n", number);
}
return 0;
}
long power(long y)
{
long i;
long j = 10;
for (i = 1; i< y; i++)
j *= 10;
return j;
}
首先,Kaprekar数字除以偶数位数(如2010,102030,2111,它有偶数位,但必须均匀)分为两部分,例如3025,分为两部分,30和25 ,和(30 + 25)^ 2 = 3025.我编写了一个程序,以便计算14位数字,但程序运行速度慢(实际上,我可以得到答案,直到8位数字(例如,24502500)。 / p>
那么,任何人都可以提供更好的算法吗?这是我的代码。
答案 0 :(得分:3)
每个2n位的Kaprekar数字是一个带有n个数字的数字的平方,因此要查找10 ^ 14以下的所有Kaprekar数字,请检查10 ^ 7以下的所有数字的平方。但是,一些n位数的平方只有2n - 1:这些不起作用。为了避免这些,对于10 <= 10 ^ 7的每个幂,从该功率开始除以10的平方根并且上升到10的幂。我编写了一个执行此操作的程序,它在0.6秒内运行。之所以这么快,是因为它只检查大约10 ^ 6.5的数字,而你的程序检查10 ^ 14。
#include <stdio.h>
#include <inttypes.h>
const uint64_t DIGITS = 14;
int main(void){
uint64_t top = 10;
for(uint64_t i = DIGITS/1; i-- > 0;){//calculate 10^(DIGITS/2) using iterated multiplication (better exponentiation is unnecessary.)
top *= 10;
}
for(uint64_t t = 10; t <= top; t *= 10){
for(uint64_t n = t*.316227766016838L; n < t; ++n){//divide t by the square root of 10 to ensure n*n has twice as many digits as n.
uint64_t k = n*n;
if(n == k%t + k/t){
printf("%"PRIu64"\n", k);
}
}
}
}
我希望这有用。