三角形数的除数(欧拉 12)

Posted

技术标签:

【中文标题】三角形数的除数(欧拉 12)【英文标题】:Divisors of triangle numbers (Euler 12) 【发布时间】:2013-08-22 14:38:54 【问题描述】:

我发现了几个与这个问题相关的主题,我只想知道为什么我的代码返回不正确的数据。 所以我们必须找到第一个具有超过 500 个除数的三角形数。详情可以在这里找到:http://projecteuler.net/problem=12 这是我的代码:

Int64 triangularnum = 1;
            for (Int64 num = 2; num > 0; num++)
            
                if(has501Divisors(triangularnum))
                
                    MessageBox.Show(triangularnum.ToString());
                    break;
                
                triangularnum += num;
            



private bool has501Divisors(Int64 candidate)
        
            bool has501 = false;
            int count = 0;
            for (int i = 1; i < Math.Sqrt(candidate); i++)
            
                if (candidate % i == 0) count += 1;
                if (count > 501)
                
                    return true;
                
            
            return has501;
        

这给了我号码 842161320,这显然是不正确的。

【问题讨论】:

您可以编写一个名为“CountDivisors”的方法,而不是编写一个方法“Has501Divisors”。通过在小数上测试和调试该方法,您很快就会发现您犯了一个错误并且低估了除数。学习如何有效地将问题分解为可测试的子系统是一项对您未来很有帮助的技能。 【参考方案1】:

您应该将您的count 编号增加2 而不是1

还有你的

if (count > 501)

部分不正确,因为您的边界应该是500 而不是501。将其更改为 count &gt; 500 而不是。

static void Main(string[] args)

    Console.WriteLine(Find());


public static int Find()

    int number = 0;
    for (int i = 1; ; i++)
    
        number += i; // number is triangle number i
        if (CountDivisorsOfNumber(number) > 500)
            return number;
    



private static int CountDivisorsOfNumber(int number)

     int count = 0;
     int end = (int)Math.Sqrt(number);
     for (int i = 1; i < end; i++)
     
         if (number % i == 0)
             count += 2;
     
     if (end * end == number) // Perfect square
         count++;
     return count;

这打印出76576500,看起来是一个正确的解决方案。

【讨论】:

【参考方案2】:

问题是您将循环限制为平方根,这很聪明,但这意味着您需要将计数增加 2,而不是增加 1 来考虑两个除数。

将增量更改为:

if (candidate % i == 0) count += 2;

此外,您的计数检查会检查大于 501 个除数,而不是 500 个。

【讨论】:

哦。谢谢,我很盲目。 @fishmong3r:另外,如果这个数字是一个正方形三角形数字呢?假设您正在计算 36 的除数,它既是正方形又是三角形。您的程序计数 1、2、3 和 4,并跳过 6、9、12、18 和 36。vcsjones 的建议增加 2 在这里并没有给您正确的答案;正确答案是 9,但建议的程序给你 8。 啊,完全正确。 Soner Gönül 的回答确实涵盖了如何正确处理这个问题。幸运的是,正确的结果不是正方形。【参考方案3】:

快速查看,但您的检查不正确:

if (count > 501)

这将停止在计数 502,而不是 501。


for (int i = 1; i < Math.Sqrt(candidate); i++)

9 可以被 3 整除,所以你应该在这里使用

【讨论】:

1不是除数吗?它似乎符合除数的定义。 这是一个微不足道的除数,但在示例中使用了它,所以是的,你是对的。

以上是关于三角形数的除数(欧拉 12)的主要内容,如果未能解决你的问题,请参考以下文章

欧拉的问题:凸多边形划分为三角形的方法数

与项目欧拉速度比较:C vs Python与Erlang vs Haskell

04 绘制正方体和位移矩阵

搅拌机;自定义导出“平面”三角形顶点

洛谷P2158- SDOI2008]仪仗队 - 莫比乌斯反演 & 欧拉函数

做一个列数等于行数的三角形