这里我将简要描述一个算法。需要注意的是,很多细节需要填写。
基本思路是看M的第一个和最后一个数字,确定N的第一个和最后一个数字之和,然后从M中减去这个数量,减少到a的情况更短的数字。
如果可以写成N + reverse(N),我们就叫一个号码好。
(编辑:在实现中,可能需要一个函数IsGood(M, k) 来判断M 是否可以写成N + reverse(N) 对于某些N < 10^k。但我们暂时跳过这个细节。)
判断给定数字M是否好用的算法如下:
让c 和d 成为M 的第一位和最后一位,让R 成为中间部分。即M有数字表达cRd。
有两种情况:
在c不等于1的情况下,数字c不能是进位。这是正常情况。现在看看d。
如果d 等于c,那么M 是好的当且仅当R 是好的。
如果d 等于c - 1,则存在从R 到c 的进位,所以M 是好的当且仅当1R 在进位情况下是好的(见下文)。
如果d 等于其他任何值,则M 不好。
在c 等于1 的情况下,c 可能是进位。
设e为R的第一位,M为1eTd。
如果d = 9 或e < d,则不能携带手提箱。
(编辑:这是错误的,d = 9 的情况可能是e = 0。)
否则,当且仅当(e - d)(T - 1) 良好时,携带箱是可能的。
如果手提箱或普通箱保持,那么M 是好的。
例子:
让我们从M = 12001开始。
c = 1起,有普通箱和手提箱。
正常情况下,我们有d = 1,所以我们需要测试200是否好。对于M = 200,我们有c = 2 和d = 0,所以200 的数字不好,因此M = 12001 的正常情况失败。
在carry case中,我们需要测试(12001 - 11000 - 11) / 10 = 99是否良好。对于M = 99,我们有c = 9 和d = 9,所以这又归结为0 是否好,这显然是正确的。因此,手提箱保持不变。
那么结论是M是好的。
时间复杂度:
通过一些详细的论据(我不想在这里展示),可以证明该算法运行在O(log_10(M))时间。