【问题标题】:How to solve timeout in this codes?如何解决此代码中的超时问题?
【发布时间】:2018-04-18 11:34:28
【问题描述】:

我需要帮助。问题是在照镜子时找到对称数。 (例如 0、1、11、101、1521 (o) 但 1221 和 1010 不是。) enter image description here 给定两个数字 A 和 B,它们之间有空格。(输入) 范围是 0

输出是打印从 A 到 B 的对称数计数。

例如)0 100(输入) 7(输出)

这是我在 C++ 中的代码,但由于数字范围宽,此代码发生超时。这个问题怎么解决?

int main()
{

    scanf("%d %d", &n,&m);

    for(int i=n;i<=m;i++)
    {
        char s[19];
        n=i;
        int len=0;

        do{ 
            s[len++]=n%10;
            n/=10; 
        } while(n>0);

        len--;
        int j = 0;

        for(j=0;j<=len/2;j++)
        {
            if(s[j]==s[len-j] && (s[j]==1 || s[j]==8 || s[j]==0))
                continue;

            if( (s[j]==2 && s[len-j]==5) || (s[j]==5 && s[len-j]==2))
                continue;

            break;
        }

        if(j>len/2)
            cnt++;
    }

    printf("%d\n",cnt);
    return 0;
}

【问题讨论】:

  • 首先:您的问题的格式确实很糟糕,以至于几乎无法阅读。请改进它。回答你的问题:我的猜测是,问题的解决方案不是不检查 A 和 B 之间的所有数字,而是只生成具有所需属性的数字 - 即,只生成不包含任何非 -可镜像的数字。

标签: algorithm timeout


【解决方案1】:

您已经经历了一个非常痛苦的过程来查看所有数字中的哪一个是镜子。 Lukas Barth 是在正确的轨道上,但它甚至比这更快。您不需要构造数字;数一数有多少。

首先,你根本不关心数字的后半部分;通过构造,给定左半边,右半边是独一无二的。因此,您所要做的就是计算每个数字长度的左半部分。这将解决完全包含在范围内的 10 次方的所有计数问题。

这使得它更加更容易。对于只有部分数字的范围(即 A 和/或 B 不是 10 的幂),您必须限制范围一端或另一端的前导数字。

您可以使用前导零。因此,每个数字有五种可能性:0、1、8、2、5。如果您有奇数个数字,则中间数字必须是它自己的镜像:0、1、8。

让我们看一个例子,4 位数字和 5 位数字。对于 4 位数字,您只需要前两个。每个数字都有 5 种可能性。这产生 5*5,或 25 four-digit mirror numbers

现在将其扩展到 5 位数字。您已经知道正好有 25 个两位数的开头。添加您的三个合法中间数字之一,得到 3*25,或 75 five-digit mirror numbers

将此扩展为完整的解决方案留给学生作为练习。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 2010-12-06
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2021-01-05
    相关资源
    最近更新 更多