【问题标题】:Pythagorean triplets whose sum is 1000?总和为 1000 的毕达哥拉斯三元组?
【发布时间】:2013-04-19 11:40:18
【问题描述】:

Project Euler 问题 9。我试图解决它,实际上我得到了不是毕达哥拉斯三元组的三元组,它们的总和是 1000,为什么?我确定他们是毕达哥拉斯三胞胎。这是我的长且未优化的代码:

#include <iostream>
#include <math.h>

using namespace std;

int main()
{
    int a,b,c; //Decalring the triplets...
    a=1; //First triplet starts with 3
    b=1;
    int c2;//c square

    while(true)
    {
        for(b=1;b<a;b++){
        c2 = a*a+b*b;
        c = sqrt(c2);
        if(c*c == c2 && a+b+c==1000)
        {
            cout<<a<<","<<b<<","<<c<<"\n";
        }
        a++;
        }
        b++;
    }
}

最终工作代码:

#include <iostream>
#include <math.h>

using namespace std;

int main()
{
    int x,y,z,a;
    for(x=1;x<=1000;x++)
    {
        for(y=1;y<=1000;y++)
        {
            a = x*x+y*y;
            z=sqrt(a);
            if(z*z==a && x+y+z==1000 && x<y){
            cout<<x<<","<<y<<","<<z<<"."<<"\n";
            cout<<"So the product of all of the three triplets is "<<x*y*z;
            }
        }
    }
    return 0;
}

【问题讨论】:

  • 您不应该检查sqrt(c2) 是否完整吗?
  • 我做了,然后它没有给我任何结果......:/

标签: c++ pythagorean


【解决方案1】:

您的循环条件已关闭。对应于当前abc 在循环内部 计算。因此,您不能在 c 的值上测试循环迭代,因为它是旧的。从条件中删除c,重新测试sqrt(c2)的完整性,你就有了解决方案。

编辑

您似乎试图通过或多或少的随机代码更改来获得结果。那不会带你去任何地方。

首先用简单的人类语言清楚地制定您的算法。然后将其改写为匹配 C++ 代码概念的(仍然是简单的人类语言)结构。然后对这些概念进行编码。

类似这样的:

步骤 1. 在毕达哥拉斯三元组中,第三个成员 c 完全由前两个决定。所以我将检查ab 的所有可能值,如果它们形成一个毕达哥拉斯三元组,则测试它的总和为1000。

第 2 步。对于每个 a,我将测试所有大于 abs,使得 a + b 小于 1000。我将计算 c2 并查看它是否是正方形。如果是这样,我将测试三元组的总和。

第 3 步。

#include <cmath>
#include <iostream>

int main()
{
  for (int a = 3; a < 1000; ++a) {
    for (int b = a + 1; a + b < 1000; ++b) {
      int c2 = a * a + b * b;
      int c = std::sqrt(c2);
      if (c * c == c2) {
        if (a + b + c == 1000) {
          std::cout << "Found triplet " << a << ", " << b << ", " << c << '\n';
        }
      }
    }
  }
}

【讨论】:

  • @Rohanchrome 好吧,现在你只测试b == a + 1 的三元组。你也应该循环b
  • 谢谢你!做到了! :D我刚开始,它就像一个魅力:D
【解决方案2】:

您应该检查以确保c2 实际上是一个正方形。一种方法是在取平方根后检查 c*c == c2 是否。

【讨论】:

  • 谢谢,我试过了,但没有结果:/可能我的逻辑有问题?
  • @Rohanchrome:最外层循环的循环条件看起来很可疑。 ac 将在循环中响应 b 而发生变化,因此您可能应该只在 while 循环的条件下检查 b
  • 应该是什么条件? b
  • @Rohanchrome:可以比这更严格(提示:使用triangle inequality),但是是的,我认为应该可以。
  • 最简单的方法是什么?两个循环都从 1 到 1000。内部 if 将丢弃任何不起作用的东西。一旦你完成了这项工作,你可以尝试通过使用诸如a &lt; ba + b + c &lt;= 1000 和三角不等式,甚至Euclid's formula 等身份来变得更聪明,但从简单开始并不羞耻。对于这个小问题,无论哪种情况,它都可能足够快。
【解决方案3】:
//My brute force solution works fine
since i<j<k
start j loop from i+1 and k loop from j+1
whenever the condition satisfies print the product of triplet

#include<iostream>
using namespace std;
int main()
{
    for(long long i=1;i<=1000;i++)
    {
        for(long long j=i+1;j<=1000;j++)
        {
            for(long long k=j+1;k<=1000;k++)
            {
                if((i+j+k)==1000 && i*i+j*j==k*k)
                {
                cout<<i*j*k<<endl;
                }
            }
        }
    }
}

【讨论】:

  • 有些人认为这是一种不好的风格,用未注释的代码和没有解释文本来回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多