幸福数字的最优算法

时间:2014-03-13 18:07:29

标签: java algorithm

给定数字为n位数,找到2n位数字 那,例如

给定数字为3,则6n数字为100000-999999

然后找到那些数字的计数,例如

       123213
1 + 2 + 3 = 2 + 1 + 3
        6 = 6 

我发现并编写了一个计算小数字的程序,但我需要最快的算法才能找到这些数字。想法?

我的节目:

Scanner scan = new Scanner(System.in);

System.out.println("enter  n ");

int say = scan.nextInt();

say *= 2;

int low = (int) Math.pow(10, say - 1);
int max = (int) Math.pow(10, say) - 1;

int counter = 0;

int first = 0;
int last = 0;

for (int i = low; i <= max; i++) {

    int number = i;
    first = 0;
    last = 0;

    for (int j = 0; j < say / 2; j++) {

        int k = number % 10;
        first += k;
        number /= 10;
    }

    for (int j = 0; j < say / 2; j++) {

        int k = number % 10;
        last += k;
        number /= 10;
    }

    if (first == last) {
        //  System.out.println(i);
        counter++;
    }
}
System.out.println(counter);

1 个答案:

答案 0 :(得分:4)

这些号码被称为俄语的幸运票(a link至ru.wikipedia.org)。然而,除了these slides之外,我似乎没有用英语找到一个很好的解释。

基本上,我们假设我们有2n个数字,我们希望第一个n的总和等于最后n的总和。我们首先计算c(d,s)d位数的序列数,其总和为s。在此处0 <= d <= n0 <= s <= 9n。这可以通过动态编程来完成:c(0,0)=1d > 0c(d,s) = c(d-1,s-0) + c(d-1,s-1) + c(d-1,s-2) + ... + c(d-1,s-9),因为我们可以采用任意d-1个数字序列并从0写入另一个数字到9

现在,幸运票的总数是不同s个幸运票数量的总和,其中第一个n数字的总和是s和总和最后n位为s。修正s后,此数字等于c(n,s) * c(n,s):正好有c(n,s)个方法可以选择上半年,同样多的方式可以选择第二个。

因此答案是sum[s=0..9n] c(n,s)^2

还有其他解决方案涉及高级数学,但对于程序员的任务,这就足够了。再一次,我找不到合适的英文来源 - 抱歉! Here是俄语中一些受欢迎的文章,因为它的价值。

修改:如果您实际上需要考虑数字100000到999999,而不是000000到999999,那么补丁就是计算sum[s=0..9n] (c'(n,s) * c(n,s)),其中c'(n,s)是相同的表,但在添加第一个数字时禁用加零数字计算。