勾股数

勾股数是最早引起人们兴趣的数学现象,在很久远的年代各名族都研究过勾股数。埃及最早发现3、4、5是一组勾股数。公元前巴比伦人就知道119、120、169是一个直角三角形的三边长。

我国在早期的《周髀算经》中就谈到“勾广三,股修四,弦隅五”,指边长为3、4、5的直角三角形。古代数学家刘徽在《九章算术》中有:
3²+4²=5² ; 5²+12²=13² ;
7²+24²=25² ; 8²+15²=17² ;
等多组勾股数的记载。

长方体数是勾股数的三维推广,本节在探索勾股数的设计求解基础上探讨长方体数的一个特例。

勾股数


我国著名的数学家华罗庚教授在他写的文章中这样说:“……如果我们宇宙航船到了一个星球上,那儿也有如我们人类一样高级的生物存在。我们用什么东西作为我们之间的媒介。带幅画去吧,那边风景特殊,不了解;带一段录音去吧,也不能沟通。我看最好带两个图形去。一个是‘数’,一个是‘数形关系’(勾股定理)。”

勾股数 又名 毕氏三元数 凡是可以构成一个直角三角形三边的一组正整数,称之为勾股数。

这里写图片描述 数形关系的图即勾股定理的示意图 ,如左图;

通常把满足三元二次方程式 x²+y²=z² 的正整数解 x、y、z 称为一组勾股数,又称为毕达哥拉斯三维数组。该方程式称为 “商高方程” 或 “毕达哥拉斯方程” ;
试探求指定区间 [a,b] 内的所有勾股数组。

1.说明:

设指定区间为 [a,b] ,设置二重循环在指定区间内枚举 x 和 y (x < y),应用勾股数的定义式计算 z=sqrt(x * x+y * y);
若 z>b 或 z 不为整数,返回;
否则,输出勾股数x、y、z

2.程序设计:

#include<stdio.h>
#include<math.h>
int main()
{
   int a,b,n;
   long x,y,z,d;
   printf("请输入区间[a,b]的上下限a,b:");
   scanf("%d,%d",&a,&b);
   printf("区间[%d,%d]中的勾股数组有:\n",a,b);
   n=0;
   for(x=a;x<=b-2;x++)
      for(y=x+1;y<=b-1;y++)
      {
         d=x*x+y*y;
         z=sqrt(d);
         if(z>b)
            break;
         if(z*z==d)
         {
            n++;
            printf("  %ld^2+%ld^2=%ld^2\n",x,y,z);
         }
      }
   printf("共%ld组勾股数。",n);
}

3.程序运行示例及其注意事项:

请输入区间[a,b]的上下限a,b:300,500
区间[300,500]中的勾股数组有:
  300^2+315^2=435^2
  300^2+400^2=500^2
  319^2+360^2=481^2
  320^2+336^2=464^2
  325^2+360^2=485^2
  340^2+357^2=493^2
共6组勾股数。

注意:题设条件中有 x < y ,且 x、y、z 均在给出的区间 [a,b] 范围内,所以 x< b-2

若要保证三边均为正整数,则不可能存在两直角边相等的情况

倒立勾股数


把求勾股数变通为求倒立的勾股数,定义满足三元二次分数方程式1/x²+1/y²=1/z²的正整数 x、y、z 称为一组倒立的勾股数;
试求指定区间 [a,b] 内的倒立勾股数组。

1.说明:
显然,倒立勾股数组中x、y不可能相等,且 x,y > z;
为了避免重复,不妨设 x>y>z;

在指定区间 [a,b] 上根据x、y、z的大小关系设置循环:z从a至b-2,y从z+1至b-1,x从y+1至b

对每一组x、y、z,如果直接运用条件式1/(x * x)+1/(y * y)=1/(z * z)进行判别,因分数计算不可避免的误差,有可能把一些成立的倒立勾股数组解遗失,即造成遗漏

注意到上述分数条件式作通分整理得到下面的正整数条件式:

z * z * z ( x * x+y * y ) = x * x * y * y

程序中为防止发生解的遗漏,应用上述整数条件进行判别是适宜的。

2.程序设计:

#include<stdio.h>
#include<math.h>
int main()
{
   int a,b,n;
   long x,y,z;
   printf("请输入区间[a,b]的上下限a,b:");
   scanf("%d,%d",&a,&b);
   printf("区间[%d,%d]中倒立的勾股数组有:\n",a,b);
   n=0;
   for(z=a;z<=b-2;z++)
      for(y=z+1;y<=b-1;y++)
         for(x=y+1;x<=b;x++)
            if(z*z*(x*x+y*y)==x*x*y*y)
            {
               n++;
               printf("  1/%ld^2+1/%ld^2=1/%ld\n",x,y,z);
            }
   printf("共%d组倒立勾股数。",n);
}

3.程序运行示例及其注意事项:

请输入区间[a,b]的上下限a,b:1,100
区间[1,100]中倒立的勾股数组有:
  1/20^2+1/15^2=1/12
  1/40^2+1/30^2=1/24
  1/60^2+1/45^2=1/36
  1/80^2+1/60^2=1/48
  1/100^2+1/75^2=1/60
共5组倒立勾股数。

注意:改程序若使用 分数条件式1/(x * x)+1/(y * y)=1/(z * z) 作为判别式也是可以的,但要注意讲x、y、z定义为double型变量;不过把分数条件式整理为 整数条件式z z (x *x+y *y)==x *x *y *y作比较是可行的,也是稳妥的。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值