长方体数

如果长方体的棱长x、y、z和体对角线长w都是正整数,就把它们叫做一组长方体数;
显然,长方体数是勾股数的推广

试求指定区间 [a,b] (1<=a< b<10000)内的长方体数组(x,y,z,w)

探求长方体数


1.说明:
所求长方体数组 [a,b] 内的正整数x、y、z、w满足:

x²+y²+z²=w²

其中a<=x<=y<=z<=w<=b,这是一个涉及4个变量x、y、z、w的二次不定方程;
为了尽可能减少无效循环,根据 a<=x<=y<=z<=w<=b 的约定设置合适的循环参量是必要的;

注意到x²<=b²/3,且根据 x<=y<=z :
设置 x: a~sqrt(b*b/3)
设置 y: x~sqrt((b*b-x*x)/2)
设置 z: y~sqrt(b*b-x*x-y*y)
据以上x、y、z的取值直接计算w:若存在整数w满足 x*x+y*y+z*z=w*w,则找出一组满足条件式的整数x、y、z、w;

若输入的区间 [a,b] 范围比较小,可能不存在长方体数,为了避免此时输出出错,设置统计解的变量 k :
若 k=0,此时无解,则作必要的无解说明。

2.程序设计:

#include<stdio.h>
#include<math.h>
int main()
{
   long a,b,d,k,x,y,z,w;
   printf("请输入区间[a,b]的上下限a,b:");
   scanf("%ld,%ld",&a,&b);
   k=0;
   for(x=a;x<=sqrt(b*b/3);x++)       /*设置枚举三重循环*/
      for(y=x;y<=sqrt((b*b-x*x)/2);y++)
         for(z=y;z<=sqrt(b*b-x*x-y*y);z++)
         {
            d=x*x+y*y+z*z;
            w=(int)sqrt(d);    /*w为x、y、z的平方和开方*/
            if(w>b)
               break;
            if(w*w==d)
            {
               k++;
               printf("%3d:  %ld,%ld,%ld,%ld\n",k,x,y,z,w);
            }
         }
   if(k>0)
      printf("在指定区间[%ld,%ld]中共有以上%ld组长方体数。\n",a,b,k);
   else
      printf("在指定范围内没有长方体数!\n");
}

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

请输入区间[a,b]的上下限a,b:100,200
  1:  101,102,126,191
  2:  102,102,119,187
  3:  102,111,114,189
  4:  102,120,120,198
  5:  104,106,112,186
  6:  104,107,116,189
  7:  108,108,126,198
  8:  108,116,117,197
在指定区间[100,200]中共有以上8组长方体数。

注意:以上输出表明,长方体数中x、y可能相等,y、z也可能相等。因此,在设置枚举循环时如果循环初值 y=x+1 开始,或者循环初值 z=y+1 开始,可能造成漏解。

六个正整数问题


加德纳(M.Gardner)是美国著名的科普专栏作家,他在1970年的《科学美国人》杂志上提出这个一般问题:
在一个长方体中,从一顶点出发的三条棱长、三个面的对角线长以及体对角线这七条线段中,能否同时出现六个正整数?

实际上,它是以下三个不同问题的综合形式:
*(1)、体对角线长是无理数,其余六条线段长是正整数;
*(2)、一条棱长是无理数,其余是正整数;
*(3)、一个面的对角线长是无理数,其余是正整数;

关于问题(1):
早在1719年, 哈克尔(P.Halcke) 已经发现,若长方体的棱长为117、44、240,则其面对角线的长度都是正整数(分别为267、244、125);
关于问题(2):
例如,取长方体的棱长为 a=124,b=957,c*c=13852800,那么各个面对角线的长度是965、3724、3843,体对角线的长度是3845。出去c是无理数之外,其余六个数都是正整数;
关于问题(3):
瑞士数学家 欧拉(L.Euler) 已经得到过该问题的一些解。其中一个的棱长是(104、153、672),另一个棱长是(117、520、756)。前者的体对角线是697,2个面对角线长是185、680,另外一个面对角线长为无理数;后者的体对角线长是925,2个面对角线长是533、765,另外一个面对角线长为无理数;

下面通过程序设计探讨指定区间上的问题(1):
在指定区间 [a,b] 内搜寻6个整数,其中三个整数是长方体的长、宽、高,另3个整数是该长方体的6个面的对角线长。

1.说明:
设长方体的 长、宽、高 分别为 x、y、z(x< y< z)(且最多存在两棱长相等),相对应面的对角线长分别为e1、e2、e3;
要使其各面对角线长e1、e2、e3都是整数,则x、y、z这三个数中每两个的平方和都应是平方数d1、d2、d3,也就是说,x、y、z中每两个都应是一组勾股数组的勾股数;

设置x、y、z三重循环:
注意到 x²< b²/2,且根据 x< y< z :
设置x: a~sqrt(b*b/2)
设置y: x+1~sqrt(b*b-x*x)
设置z: y+1~sqrt(b*b-x*x)

计算x、y的平方和赋给d1,d1再开方取整数赋给e1,即 d1=x* x+y* y ,e1=(int)sqrt(d1),若 d1=e1*e1,说明x、y为边长的面的对角线长e1为整数;
同样,判别以x、z为边长与以y、z为边长的面的对角线长是否为整数,当这三个判别同时满足时,输出一组“6个整数”的解;

2.程序设计:

#include<stdio.h>
#include<math.h>
int main()
{
   long a,b,x,y,z,e1,e2,e3,d1,d2,d3,n=0;
   printf("请输入区间[a,b]的上下限a,b:");
   scanf("%ld,%ld",&a,&b);
   for(x=a;x<sqrt(b*b/2);x++)
   {
      for(y=x+1;y<=sqrt(b*b-x*x);y++)
      {
         d1=x*x+y*y;
         e1=(long)sqrt(d1);
         if(d1==e1*e1&&e1<b)
         {
            for(z=y+1;z<=sqrt(b*b-x*x);z++)
            {
               d2=x*x+z*z;
               e2=(long)sqrt(d2);
               d3=z*z+y*y;
               e3=(long)sqrt(d3);
               if(d2==e2*e2&&d3==e3*e3&&e2<b&e3<=b)
               {
                  n++;
                  printf("NO%ld:",n);
                  printf("%ld,%ld,%ld\n",x,y,z);
                  printf("各面对角线长:");
                  printf(" L1(%ld,%ld)=%ld",x,y,e1);
                  printf(" L2(%ld,%ld)=%ld",x,z,e2);
                  printf(" L3(%ld,%ld)=%ld\n",y,z,e3);
                  break;
               }
            }
         }
      }
   }
}

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

请输入区间[a,b]的上下限a,b:1000,2000
NO1:1008,1100,1155
各面对角线长: L1(1008,1100)=1492 L2(1008,1155)=1533           L3(1100,1155)=1595
NO2:1200,1260,1375
各面对角线长: L1(1200,1260)=1740 L2(1200,1375)=1825 L3(1260,1375)=1865

完美长方体

如果有一个长方体,它的所有棱长、所有面对角线长和体对角线长都是正整数,则称它为完美长方体(Perfect Cuboid)
是否存在完美长方体?这是个著名的难题,至今还不知道答案。

一个非常自然的想法是,在”六个正整数“解答的基础上继续探索;
现有的探索结果还是两手空空,无法断言是否存在完美长方体。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值