【问题标题】:Finding all pythagorean triplets between 100 to 1000查找 100 到 1000 之间的所有毕达哥拉斯三元组
【发布时间】:2016-01-19 10:15:15
【问题描述】:

我编写了一个程序来查找 100 到 1000 之间的毕达哥拉斯三元组。 这是相同的代码。

#include<iostream>
#include<cmath>

using namespace std;

bool checkWhetherInteger(int x, int y);
int getInteger(int x, int y);

int main() 
{
    cout << "This program is to print all pythagorean triplets from 100 to 1000. \n";

    int x=100;
    int y=100;

    for(; x<=1000; x++)
    {
        for (; y<=1000; y++)
        {
            if (checkWhetherInteger(x,y))
            {
                cout << "Triplet : " << x << "  " << y << "  " << getInteger(x,y) << "\n";
            }
        }
        y=100;
    }
    return 0;
}

bool checkWhetherInteger(int x, int y)
{
    for (int i=141; i<=1415; i++)
    {
        if(hypot(x,y) == i )
        {
            return true;
        }
    }
}

int getInteger(int x, int y)
{
    return static_cast<int>(hypot(x,y));

}

我现在面临两个问题。

  1. 主要问题是它执行缓慢。虽然它给了我所有的三元组,但它需要大约 553.7 秒来执行。那么有没有什么算法可以在 1-2 秒或更短的时间内完成我想要实现的目标。

  2. 由于两个自变量 x 和 y,我得到一个三元组两次。对此可以做些什么。

如果我做错了什么,请多多包涵。我是一名学习者。

【问题讨论】:

  • 您有三个嵌套循环,每个循环运行大约 1000 次。这使得内部代码运行了大约十亿次。可能需要一段时间!我想也许你可以通过double h = hypot(x,y); return h == int(h); 让它运行速度提高 1000 倍。
  • 成功了!在不到 3 秒的时间内执行;顺便说一句,你能告诉 int() 是做什么的吗?
  • 你为什么不使用已经计算好的结果,比如使用开局书的国际象棋程序?您将在几毫秒内获得结果! (“思考不同”——史蒂夫·乔布斯)^^
  • @Vaibhav - int(h) 正在使用构造函数样式转换转换为 int。在 C 中,它会写成(int)h
  • 你有UB,因为你可能不会在checkWhetherInteger返回。

标签: c++ c++11 cmath pythagorean triplet


【解决方案1】:

找到所有三元组的最快方法是使用以下公式:

a = k(x^2 - y^2)
b = k(2xy)
c = k(x^2 + y^2)

https://en.wikipedia.org/wiki/Pythagorean_triple

删除重复项的标准(也是最快的方法之一):使用 std::set.

代码示例:

#include <iostream>
#include <string>
#include <vector>
#include <set>

struct Triple {
  int a;
  int b;
  int c;
};

struct comp {
  inline bool operator ()(const Triple & first, const Triple & second) const {
    if (first.a != second.a) {
      return first.a < second.a;
    }
    if (first.b != second.b) {
      return first.b < second.b;
    }
    return first.c < second.c;
  }
};

int main() {
  int n = 1000;
  std::set<Triple, comp> set;
  for (int x = 2; x <= n; ++x) {
    for (int y = 1; y < x && x * x + y * y <= n; ++y) {
      int a = x * x - y * y;
      int b = 2 * x * y;
      if (a > b) {
        std::swap(a, b);
      }
      int c = x * x + y * y;
      for (int k = 1; k * c <= n; ++k) {
        if (a * k >= 100 && a * k <= n &&
            b * k >= 100 && b * k <= n &&
            c * k >= 100 && c * k <= n)
        set.insert({k * a, k * b, k * c});
      }
    }
  }
  for (const auto & triple : set) {
    std::cout << triple.a << " " << triple.b << " " << triple.c << std::endl;
  }
  return 0;
}

coliru

【讨论】:

    猜你喜欢
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多