【问题标题】:Algorithm to determine whether a given number N can become hypotenuse of right triangle with all 3 integral sides确定给定数 N 是否可以成为具有所有 3 个整数边的直角三角形的斜边的算法
【发布时间】:2013-10-20 09:49:56
【问题描述】:

假设给定一个直角三角形的斜边,那么如何确定给定的斜边是否有两个整数更小的边。

例如,给定斜边为 5。然后您必须确定给定直角三角形是否有更小的整数边。答案将是 yes,因为我们可以有更小的边为 3 和 4,因此得到一个 3-4-5 直角三角形。

同样,对于斜边 7,我们不能有这样的直角三角形。

换句话说,我们必须找出一个给定的数 N 是否可以作为一个直角三角形的斜边,该三角形的所有 3 个边都是整数。

我在Pythagorean triples 上浏览了整篇文章,但仍然没有成功。我不知道要检查什么条件。请帮忙。

【问题讨论】:

  • 您需要的复杂度是多少。 IMO 这可以建模为 2-SUM 问题。
  • 给定的斜边总是整数吗?
  • 是的,所有三个边都必须是整数。 “换句话说,我们必须找出给定的数 N 是否可以作为直角三角形的斜边,而直角三角形的所有 3 个边都是整数。”

标签: java c++ c algorithm geometry


【解决方案1】:

你有一个原始毕达哥拉斯三元组:

(p^2 - q^2)^2 + (2 * p * q))^2 = (p^2 + q^2)^2 = N^2

假设 p >= q。然后我们有

N >= 2 * q^2 or q <= sqrt(N / 2)

假设 N = 13。那么我们需要 q

q = 2 => p^2 = 13 - 4 = 9,这是一个正方形。

因此,您可以从 1..sqrt(N/2) 中获得一个数字“i”的小循环,并检查 N - (i^2) 是否为正方形。

对于 primitive 毕达哥拉斯元组的成员,这将是 O(sqrt(N))

C/C++ 示例代码:

#include <stdio.h>
#include <math.h>

void CheckTuple(int n)
{
    int k = sqrt(n/2.0);

    for (int i = 1; i <= k; i++) {
        int tmp = sqrt((double)(n - i * i));
        if ((tmp * tmp) == (n - i * i)) {
            printf("%d^2 + %d^2 = %d^2\n", (tmp*tmp - i*i), 2 * tmp * i, n);
            return;
        }
    }
    printf("%d is not part of a tuple\n", n);
    return;
}


int main(int argc, char *argv[])
{

    CheckTuple(5);
    CheckTuple(6);
    CheckTuple(13);
    CheckTuple(10);
    CheckTuple(25);

    return 0;
}

输出:

3^2 + 4^2 = 5^2
6 is not part of a tuple
5^2 + 12^2 = 13^2
8^2 + 6^2 = 10^2
7^2 + 24^2 = 25^2

【讨论】:

  • 它并不总是给出正确的答案。因为 51 可能是斜边,但事实证明不是。
  • @lavee_singh:抱歉回复晚了。是的,上面找到了 basic / primary 毕达哥拉斯元组。 51^2 = 24^2 + 45^2 是从基本的17^2 = 8^2 + 15^2 派生而来的,我们不会得到前者,但会得到后者。
  • 好的,现在我们必须标记所有已经找到的斜边的倍数,以防止出现这种错误!
【解决方案2】:

这个问题一直是我在网上搜索最多的话题之一。但解决方案很简单。得出答案,让 n 可以是直角三角形的斜边。 n^2 = a^2 + b^2。 (n,a 和 b 是整数)。那么显然对于任何整数 k,k*n 可以是斜边。 (4*l+1) 形式的任何素数都可以是斜边(l 是整数)。因此,将一个数字拆分为其主要因素。如果至少一个素因数的形式是 4*l+1 ,那么显然这个数可以是斜边。 例如:5 可以表示为 4*1+1 和 5^2 = 3^2 + 4^2。同样,78 = 2*3*13 和 13可以表示为4*3+1。和 13^2 = 5^2 + 12^2 =>78^2 = 30^2 + 72^2

【讨论】:

    【解决方案3】:

    这个呢?

    • “较小的”边显然应该小于三角形的斜边。
    • 我们将需要另外两个方面。

    -> 2 个 for 循环继续到斜边。像这样的:

    public static boolean isAnIntegerTriangle(int hypotenuse) {
        for (int i = 0; i < hypotenuse; i++) {
            for (int j = 0; j < hypotenuse; j++) {
                boolean b = ((hypotenuse * hypotenuse) == (i * i + j * j));
                if (b)
                    return true;
            }
        }
        return false;
    }
    

    测试:

    public static void main(String[] args) {
        System.out.println(isAnIntegerTriangle(5));
        System.out.println(isAnIntegerTriangle(10));
        System.out.println(isAnIntegerTriangle(7));
    }
    

    输出:

    true
    true
    false
    

    【讨论】:

      【解决方案4】:
      int hypo = 5, i;
      double other = 0;
      for (i=1;i<hypo;i++)
      {
          other = Math.sqrt(hypo*hypo - i*i);
          if (other == (int)other)
              break;
      }
      
      if (i<hypo)
         System.out.println("Yes - (" + (int)other + ", " + i +")" );
      else
         System.out.println("No");
      

      O(N)

      【讨论】:

        【解决方案5】:

        编辑:不需要执行以下步骤,因为它总是返回 false。

        //For each element in the array check whether twice its value equals N^2. If no match occurs then continue to the following.
        

        .

        Have two counters I1 and I2 -> Initialize I1 = 1 and I2 = N-1.
        1. Check the sum I1^2 + I2^2;  
        2. If the sum is > N^2, decrement the right counter (I2).  
        3. If it is < N^2, increment the left counter (I1).
        
        Keep doing the above 3 statements until one of the following happens.    
        -> If the sum matches N^2, then a right angled triangle can be formed.
        -> If I2 <= I1, then it is not possible to form a triangle.
        

        复杂度:O(N)

        编辑:正如 Dukeling 指出的那样,没有必要存储数组。您可以直接对 I1 和 I2 进行平方。

        【讨论】:

        • 我花了几分钟才明白这一点,但它实际上非常优雅。我喜欢它。
        • 创建数组是不必要的(而且效率低下)。您可以循环遍历数字 1 到 N-1,然后将它们平方。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-05
        • 1970-01-01
        • 2017-04-09
        • 2016-01-07
        • 2022-11-10
        相关资源
        最近更新 更多