如何以更好的方式计算Kaprekar数?

时间:2016-06-23 10:51:50

标签: c algorithm

#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>

那么,任何人都可以提供更好的算法吗?这是我的代码。

1 个答案:

答案 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);
            }
        }
    }
}

我希望这有用。