鱼C论坛

 找回密码
 立即注册
楼主: 欧拉计划

题目9:找出唯一的满足a + b + c = 1000的毕达哥拉斯三元组{a, b, c}

[复制链接]
发表于 2022-1-2 13:20:57 | 显示全部楼层
本帖最后由 guosl 于 2022-1-3 21:29 编辑

本题可以应用本原直角三角形的参数形式来解。
  1. /*
  2. 答案:31875000
  3. 耗时:0.0000023秒
  4. */
  5. #include <iostream>
  6. #include <cmath>
  7. using namespace std;

  8. int gcd(int x, int y)//本原直角三角形的两个参数必须互素
  9. {
  10.   if (y == 0)
  11.     return x;
  12.   int z = x % y;
  13.   while (z != 0)
  14.   {
  15.     x = y;
  16.     y = z;
  17.     z = x % y;
  18.   }
  19.   return y;
  20. }

  21. int chk(int n)//检查是否存在边长为k的本原直角三角形
  22. {
  23.   int d = (int)sqrt((double)n);
  24.   for (int i = 1; i <= d; ++i)//枚举本原直角三角形的大参数
  25.   {
  26.     if (n % i == 0)
  27.     {
  28.       int p = n / i;
  29.       if (gcd(i, p) == 1)
  30.       {
  31.         int x = i, y = p - i; //解出本原直角三角形的两个可能的参数
  32.         if (x > y && ((x - y) & 1) != 0)//检查是否合法
  33.         {
  34.           //根据x,y算出本原直角三角形的三个边长
  35.           int a = x * x - y * y;
  36.           int b = 2 * x * y;
  37.           int c = x * x + y * y;
  38.           return a * b * c;
  39.         }
  40.       }
  41.     }
  42.   }
  43.   return 0;
  44. }

  45. int main(void)
  46. {
  47.   for (int k = 1; k <= 22; ++k)//枚举此直角三角形与本原直角三角形的边长倍数
  48.   {
  49.     if (500 % k == 0)
  50.     {
  51.       int p = chk(k);//检查是否存在边长为k的本原直角三角形
  52.       if (p > 0)
  53.       {
  54.         int k1 = (500 / k);
  55.         k1 = k1 * k1 * k1;
  56.         p = p * k1;//存在则保存结果
  57.       }
  58.       if (p == 0)
  59.       {
  60.         p = chk(500 / k);//检查是否存在边长为500/k的本原直角三角形
  61.         if (p > 0)
  62.           p = p * k * k * k;//存在则保存结果
  63.       }
  64.       if (p > 0)
  65.       {
  66.         cout << p << endl;//输出结果
  67.         break;
  68.       }
  69.     }
  70.   }
  71.   return 0;
  72. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-28 21:06:10 | 显示全部楼层
  1. #include <cstdio>
  2. int main()
  3. {
  4.     for(int a=1;a<1000;a++)
  5.         for(int b=1;b<1000;b++)
  6.         {
  7.             int c = 1000-a-b;
  8.             if(c*c==a*a+b*b)
  9.             {
  10.                 printf("%d^2 + %d^2 = %d^2",a,b,c);
  11.                 return 0;
  12.             }
  13.         }
  14. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-2-22 17:23:32 | 显示全部楼层
答案(200,375,425) 循环嵌套穷举即可
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         int a,b,c;
  5.         for(a=1;a<=1000;a++)
  6.         {
  7.                 for(b=1;b<=1000;b++)
  8.                 {
  9.                         for(c=1;c<=1000;c++)
  10.                         {
  11.                                 if(a*a+b*b==c*c&&a+b+c==1000)
  12.                                 {
  13.                                         printf("(%d,%d,%d)",a,b,c);
  14.                                         return 0;
  15.                                 }
  16.                         }
  17.                 }
  18.         }
  19. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-18 16:18:04 | 显示全部楼层
本帖最后由 B1tetheDust 于 2022-3-18 16:24 编辑
  1. import time

  2. start = time.perf_counter()


  3. class Found(Exception):
  4.     pass


  5. try:
  6.     for a in range(1, 999):
  7.         for b in range(a, 999-a):
  8.             c = 1000 - a - b
  9.             if (a + b < c) or (a + c < b):
  10.                 continue
  11.             if (a**2 + b**2 == c**2) or (a**2 + c**2 == b**2):
  12.                 print('a * b * c = %d * %d * %d = %d' % (a, b, c, a*b*c))
  13.                 raise Found
  14. except Found:
  15.     print('It costs %f s' % (time.perf_counter() - start))
复制代码

运行结果:
a * b * c = 200 * 375 * 425 = 31875000
It costs 0.051990 s
偶然间犯了一个错发现:把continue改为break甚至会更快
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-6-5 17:41:03 | 显示全部楼层
  1. #include <stdio.h>

  2. int main()
  3. {
  4.         int a,b,c;
  5.         for(a=1;a<=1000;a++)
  6.         {
  7.                 for(b=1;b<=1000;b++)
  8.                 {
  9.                         if((1000-a-b)*(1000-a-b)==(a*a+b*b))
  10.                         {
  11.                                 printf("%d %d %d",a,b,1000-a-b);
  12.                                 goto end;
  13.                         }
  14.                 }
  15.         }
  16.         end:
  17.         return 0;
  18. }
复制代码

这几天在看自己以前写的代码,才发现优化空间很大
time:0.03025s
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-8 10:53:45 | 显示全部楼层
  1. use rayon::prelude::*;
  2. use std::time::Instant;


  3. fn main() {
  4.     let now = Instant::now();
  5.     (1..333i32).for_each(|a| {
  6.         (1..500i32).into_par_iter().for_each(|b| {
  7.             let c = 1000 - a - b;
  8.             if a.pow(2) + b.pow(2) == c.pow(2) {
  9.                 println!("a({a}) * b({b}) * c({c}) = {}", a * b * c)
  10.             }
  11.         })
  12.     });
  13.     println!("耗时{}秒。", now.elapsed().as_secs_f32())
  14. }
复制代码

---
a(200) * b(375) * c(425) = 31875000
耗时0.0070322秒。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-1 23:40:48 | 显示全部楼层
  1. import time
  2. start = time.time()
  3. for a in range(1, 1000):
  4.     for b in range(a+1, 1000):
  5.         c = 1000 - a - b
  6.         if a**2 + b**2 == c**2:
  7.             print(f'a={a}, b={b}, c={c}, number={c**2}')
  8.             break
  9.         else:
  10.             continue
  11. end = time.time()
  12. print(f'time:{end - start}')
复制代码

a=200, b=375, c=425, number=180625
time:0.4737279415130615
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-4-8 21:18:00 | 显示全部楼层
  1. for i in range(1,333):
  2.     for j in range(i+1,500):
  3.         if i*i+j*j==(1000-i-j)*(1000-i-j):
  4.             print(i*j*(1000-i-j))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-10 02:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表