给定数字为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);
答案 0 :(得分:4)
这些号码被称为俄语的幸运票(a link至ru.wikipedia.org)。然而,除了these slides之外,我似乎没有用英语找到一个很好的解释。
基本上,我们假设我们有2n
个数字,我们希望第一个n
的总和等于最后n
的总和。我们首先计算c(d,s)
:d
位数的序列数,其总和为s
。在此处0 <= d <= n
和0 <= s <= 9n
。这可以通过动态编程来完成:c(0,0)=1
和d > 0
,c(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)
是相同的表,但在添加第一个数字时禁用加零数字计算。