我看到很多人回答了关于溢出的问题,但我想解决他的原始问题。他说问题是要找到一个b=c的a,使得所有数字都不重复。好吧,在这篇文章中他没有问这个,但我仍然认为有必要研究问题的上限并得出结论,他永远不需要计算或检测溢出(注意:我不精通数学,所以我一步一步地做了这一步,但最终结果非常简单,可能有一个简单的公式)。
主要问题在于问题要求a、b或c的上限为98,765,432。无论如何,从将问题分为简单和非简单两部分开始:
- x0 == 1 (9、8、7、6、5、4、3、2的所有排列都是解决方案)
- x1 == x (没有解决方案)
- 0b == 0 (没有解决方案)
- 1b == 1 (没有解决方案)
- ab, a > 1, b > 1 (非简单)
现在我们只需要展示没有其他解决方案是可行的,只有排列是有效的(然后打印它们的代码是简单的)。我们回到上限。实际上,该问题的上限为c ≤ 98,765,432。这是上限,因为它是具有8位数字(总共10个数字减去每个a和b的1)的最大数字。这个上限仅适用于c,因为由于指数增长,a和b的范围必须要低得多,我们可以计算出,在将b从2变化到上限的情况下:
9938.08^2 == 98765432
462.241^3 == 98765432
99.6899^4 == 98765432
39.7119^5 == 98765432
21.4998^6 == 98765432
13.8703^7 == 98765432
9.98448^8 == 98765432
7.73196^9 == 98765432
6.30174^10 == 98765432
5.33068^11 == 98765432
4.63679^12 == 98765432
4.12069^13 == 98765432
3.72429^14 == 98765432
3.41172^15 == 98765432
3.15982^16 == 98765432
2.95305^17 == 98765432
2.78064^18 == 98765432
2.63493^19 == 98765432
2.51033^20 == 98765432
2.40268^21 == 98765432
2.30883^22 == 98765432
2.22634^23 == 98765432
2.15332^24 == 98765432
2.08826^25 == 98765432
2.02995^26 == 98765432
1.97741^27 == 98765432
例如,注意最后一行:它说1.97^27约等于98M。例如,1^27 == 1而2^27 == 134,217,728,这不是一个解决方案,因为它有9个数字(2 > 1.97所以它实际上比应该被测试的更大)。正如可以看到的那样,用于测试a和b的可用组合非常少。对于b == 14,我们需要尝试2和3。对于b == 3,我们从2开始,直到停止在462。所有结果都保证小于~98M。
现在只需测试上述所有组合,并寻找其中不重复任何数字的组合。
['0', '2', '4', '5', '6', '7', '8'] 84^2 = 7056
['1', '2', '3', '4', '5', '8', '9'] 59^2 = 3481
['0', '1', '2', '3', '4', '5', '8', '9'] 59^2 = 3481 (+leading zero)
['1', '2', '3', '5', '8'] 8^3 = 512
['0', '1', '2', '3', '5', '8'] 8^3 = 512 (+leading zero)
['1', '2', '4', '6'] 4^2 = 16
['0', '1', '2', '4', '6'] 4^2 = 16 (+leading zero)
['1', '2', '4', '6'] 2^4 = 16
['0', '1', '2', '4', '6'] 2^4 = 16 (+leading zero)
['1', '2', '8', '9'] 9^2 = 81
['0', '1', '2', '8', '9'] 9^2 = 81 (+leading zero)
['1', '3', '4', '8'] 3^4 = 81
['0', '1', '3', '4', '8'] 3^4 = 81 (+leading zero)
['2', '3', '6', '7', '9'] 3^6 = 729
['0', '2', '3', '6', '7', '9'] 3^6 = 729 (+leading zero)
['2', '3', '8'] 2^3 = 8
['0', '2', '3', '8'] 2^3 = 8 (+leading zero)
['2', '3', '9'] 3^2 = 9
['0', '2', '3', '9'] 3^2 = 9 (+leading zero)
['2', '4', '6', '8'] 8^2 = 64
['0', '2', '4', '6', '8'] 8^2 = 64 (+leading zero)
['2', '4', '7', '9'] 7^2 = 49
['0', '2', '4', '7', '9'] 7^2 = 49 (+leading zero)
没有一个匹配问题(这也可以从缺少“0”、“1”、…、“9”中看出)。
以下是解决它的示例代码。请注意,它是用Python编写的,不是因为它需要任意精度整数(代码不计算比9800万更大的任何内容),而是因为我们发现测试量太小,应该使用高级别语言来利用其内置容器和库(另请注意:该代码有28行)。
import math
m = 98765432
l = []
for i in xrange(2, 98765432):
inv = 1.0/i
r = m**inv
if (r < 2.0): break
top = int(math.floor(r))
assert(top <= m)
for j in xrange(2, top+1):
s = str(i) + str(j) + str(j**i)
l.append((sorted(s), i, j, j**i))
assert(j**i <= m)
l.sort()
for s, i, j, ji in l:
assert(ji <= m)
ss = sorted(set(s))
if s == ss:
print '%s %d^%d = %d' % (s, i, j, ji)
s = ['0'] + s
ss = sorted(set(s))
if s == ss:
print '%s %d^%d = %d (+leading zero)' % (s, i, j, ji)
-ftrapv
将导致在(有符号)整数溢出时生成一个SIGABRT信号。详见此处。 - nibotclz
指令或__clz(unsigned)
函数来确定数字的等级(其最高位在哪里)。由于我不确定这是否适用于x86或x64,因此我假设它不可用,并且说找到最高有效位将需要最多log(sizeof(int)*8)
条指令。 - nonsensickle