【问题标题】:Efficiently find the smallest 'steady number' larger than a given integer有效地找到大于给定整数的最小“稳定数”
【发布时间】:2019-11-30 20:54:37
【问题描述】:

如果奇数位的数字总和等于偶数位的数字总和,我们称一个数字为“稳定的”。例如 132 或 4059。给定一个数字 N,程序应输出大于 N 的最小/第一个“稳定”数字。例如,如果 N = 4,则答案 = 11,如果 N = 123123,则答案 = 123134。 但限制是 N 可能非常大。 N的位数可以是100。时间限制是1秒。

我的方法是将N作为字符串存储在int类型数组中的每个数字并使用长算法加1,而不是测试数字是否稳定,如果是则输出它,如果否再次添加1并测试如果它是稳定的。这样做直到你得到答案。

它适用于许多测试,但是当oddSum 和EvenSum 之间的差异非常大时,例如9090909090 程序超过时间限制。我想不出其他算法。直觉上,我认为可能有一些模式可以相互交换几个最后的数字,并在必要时为它们添加或减去一些东西,但我不知道。我更喜欢一个好的提示而不是答案,因为我想自己做。

【问题讨论】:

  • 看奇数位和偶数位的区别。你能从差异中看出你必须至少增加多少吗? IE。对于 4,区别是 4,这是否告诉您,您不必尝试 5?还是6?或者....

标签: algorithm


【解决方案1】:

使用您将使用的算法。它是这样的:

输入:9090909090

输入:9090909090 奇数:0 偶数:45

输入:909090909?奇数:0 偶数:45
显然没有数字会起作用,我们最多可以使奇数 9

输入:90909090??奇数:0 偶数:36
显然没有数字会起作用,我们去掉了一个 9 并且没有更大的数字(我们必须使数字更大)

输入:9090909???奇数:0 偶数:36
显然没有数字会起作用。偶数大于奇数,我们只能将奇数加到 18

输入:909090????奇数:0 偶数:27 显然没有数字会起作用,我们删除了一个 9

输入:90909?????奇数:0 偶数:27 也许 9 会起作用。

输入:909099????奇数:9 偶数:27 零是可能起作用的最小数字

输入:9090990???奇数:9 偶数:27 我们还需要 18 个,而且只有两位数,所以 9 是可以工作的最小数字

输入:90909909??奇数:18 偶数:27 零是可以工作的最小数字。

输入:909099090?奇数:18 偶数:27 9是唯一可以工作的数字

输入:9090990909 奇数:27 偶数:27 成功

你看到方法了吗?在无法解决时删除数字,然后将它们添加回来,直到找到解决方案。首先,删除数字,直到有可能解决。只能使用您删除的号码以外的号码。然后在每个阶段使用尽可能小的数字将数字加回来,直到找到解决方案。

【讨论】:

    【解决方案2】:

    你可以试试Digit DP technique . 你的参数可以是recur(pos,oddsum,evensum,str) 您的状态转换将是这样的:

    bool ans=0 
    for(int i=0;i<10;i++)
    {
        ans|=recur(pos+1,oddsum+(pos%2?i:0),evensum+(pos%2?i:0),str+(i+'0') 
        if(ans) return 1;
    
    }
    

    基本情况:

    if(pos>=n) return oddsum==evensum;
    

    记忆:你只需要在你的 DP 数组中保存 pos,oddsum,evensum。所以你的 DP 数组将是DP[100][100*10][100*10]。这是 10^8,会导致 MLE,你必须修剪一些内存。

    作为oddsum+evensum&lt;9*100,我们可以只有一个参数 SUM 并在奇数/偶数时加/减。所以我们的新递归将如下所示:
    recur(pos,sum,str) 状态转换是这样的:

    bool ans=0 
    for(int i=0;i<10;i++)
    {
        ans|=recur(pos+1,SUM+(pos%2?i:-i),str+(i+'0') 
        if(ans) return 1;
    }
    

    基本情况:

    if(pos>=n) return SUM==0;
    

    记忆:现在我们的 Dp 数组将是具有 [pos][sum] 的 2d 数组。我们可以说DP[100][10*100]

    【讨论】:

      【解决方案3】:

      找到总和较小的奇偶校验。从该奇偶校验的最小数字开始,将该奇偶校验的数字增加到最小的 9 和所需的剩余增量。

      这会让你得到一个更大的稳定数字,但它可能太大了。

      例如,107 得到 187,但 110 可以。

      接下来,反复减少稳定数中每个奇偶校验位最大位置的非零数字的值,这样做不会使我们低于目标。

      187,176,165,154,143,132,121,110

      所写的最后一步与递减次数呈线性关系。这已经足够快了,因为它们最多有 9*digits,但它可以优化。

      【讨论】:

        猜你喜欢
        • 2017-03-05
        • 1970-01-01
        • 2021-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多