您的位置:首页 > 编程语言 > C语言/C++

埃及分数式

2017-01-06 09:20 645 查看

埃及分数简介

金字塔的故乡埃及也是数学的发源地之一,古埃及数系中,记数常采用分子为1的分数,称为“埃及分数”;

人们研究较多且颇感兴趣的问题是:

把一个给定的整数或分数转化为若干个不相同的埃及分数之和,常约定分解式中不得包含与待分解分数同分母的埃及分数,当然,转化的方法可能有很多种,常把分解式中的埃及分数的个数最少或在个数相同时埃及分数中最大分母为最小的分解式称为最优分解式;

把给定整数或分数分解为埃及分数之和,分解与优化往往是一个烦琐艰辛的过程;

例如对5/121,可以分解为:

5/121=1/61+1/62+1/121+3/3782+1/7381+1/7382+1/54486542

为了尽可能减少分解项数,1969年数学家 布雷策 在《数学游览》中给出了以下优化的三项分解式:

5/121=1/25+1/759+1/208725

同时布雷策证明了: 5/121不可能分解为两个埃及分数之和

从项数来说,上述三项分解式不可能再优化了,但对最大分母来说,布雷策的分解式并不是最优的,我国两位青年数学爱好者于1983年发现:

5/121=1/27+1/297+1/1089

5/121=1/33+1/99+1/1089

5/121=1/33+1/121+1/363

5/121=1/33+1/91+1/33033

这4个分解式都比布雷策的结论要优,按通常约定分解式中不得包含与待分解分数同分母的埃及分数,显然应把第3个分解式排除在外,因此,现在所知把5/121分解为3个埃及分数的最小分母为1089;

那么,分解5/121为3个埃及分数之和,其最大分母能否小于1089呢?我们可以通过程序设计来探索;

构建3个埃及分数的分数式

1.说明:

设指定的分数m/d的3个埃及分数的分母分别为a、b、c(a< b< c),最大分母不超过z,通过二重循环实施枚举;

确定a循环的起始值a1与终止值a2为:

1/a1=m/d-2/z =》 a1=dz/(mz-2d)(即把b、c全放大为z);

a2=3d/m+1 (即把b、c全缩减为a);

b循环起始取a+1,终止取z-1;

对于a、b二重循环的每一组a、b,由1/c=m/d-(1/a+1/b)即可确定:

a=abd/(mab-d(a+b))

计算x=abd,y=mab-d(a+b);

如果y>0且y整除x,即得整数c,此时如果c>b且c!=d,即得分解为3个埃及分数的分数式,打印输出后退出内循环,继续寻找;

2.程序设计:

#include<stdio.h>
int main()
{
int a1,a2,a,b,c,d,e,m,n,z;
long x,y;
printf("确定分数m/d,请输入m,d:");
scanf("%d,%d",&m,&d);
printf("请确定分母的上限:");
scanf("%d",&z);
printf("把分数%d/%d分解为三个埃及分数之和:\n",m,d);
n=0;
a1=d*z/(m*z-2*d);
a2=d*3/m+1;
for(a=a1;a<=a2;a++)       /*构建二重循环枚举*/
for(b=a+1;b<=z-1;b++)
{
e=0;
if(a==d || b==d)
continue;
x=a*b*d;            /*计算x、y值*/
y=m*a*b-d*(a+b);
if(y>0 && x%y==0)
{
c=x/y;
e=1;             /*判断并计算整数c*/
}
if(e==1 && c<=z && c>b && c!=d)
{
n=n+1;
printf("NO%d:%d/%d=1/%d+1/%d+1/%d \n",n,m,d,a,b,c);
break;
}
}
printf("共上述%d个分数式\n",n);
}


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

确定分数m/d,请输入m,d:5,121
请确定分母的上限:1100
把分数5/121分解为三个埃及分数之和:
NO1:5/121=1/27+1/297+1/1089
NO2:5/121=1/33+1/99+1/1089
NO3:5/121=1/45+1/55+1/1089
共上述3个分数式


这样,我们通过程序设计探索得到:

把分数5/121分解为3个埃及分数式,最大分母至少为1089,即不可能有比上述3个分解式更优的分解;

结果中的最后一个分解式是程序设计探索到的一个新的最优分解式;

构建4个埃及分数分数式

有资料指出,如果把5/121分解为4个埃及分数之和,其分母能否小于1089呢?对于这一还没有定论的分解问题,我们继续应用程序设计进行探索;

1.说明:

设指定的分数m/d的4个埃及分数的分母分别为a、b、c、e(a< b< c< e),最大分母不超过z,通过三重循环实施枚举;

确定a循环的起始值a1与终止值a2为:

1/a1=m/d-3/z =》 a1=dz/(mz-3d)(即把b、c、e全放大为z);

a2=d*4/m+1 (即把b、c、e全缩减为a);

b循环起始取a+1,终止取z-2;

c循环起始取b+1,终止取z-1;

对于a、b、c三重循环的每一组a、b、c,由1/e=m/d-(1/a+1/b+1/c)即可确定:

e=abcd/(mabc-d(ab+bc+ca));

计算x=abcd,y=mabc-d(ab+bc+ca)

如果y>0且y整除x,即得整数e,此时如果e>c且e!=d,即得分解为4个埃及分数的分数式,打印输出后退出内循环,继续寻求;

2.程序设计:

#include<stdio.h>
int main()
{
int a1,a2,a,b,c,e,d,f,m,n,z;
long x,y;
printf("确定分数m/d,请输入m,d:");
scanf("%d,%d",&m,&d);
printf("请确定分母的上届:");
scanf("%d",&z);
printf("把分数%d/%d分解为4个埃及分数之和:\n",m,d);
n=0;
a1=d*z/(m*z-3*d);
a2=d*4/m+1;
for(a=a1;a<=a2;a++)        /*构建三重枚举循环*/
for(b=a+1;b<=z-2;b++)
for(c=b+1;c<=z-1;c++)
{
f=0;
if(b==d || c==d || a==d)
continue;
x=a*b*c*d;        /*计算x、y值*/
y=m*a*b*c-d*(a*b+b*c+c*a);
if(y>0 && x%y==0) /*判断并计算整数e*/
{
e=x/y;
f=1;
}
if(f==1 && e<=z && e>c && e!=d)
{
n=n+1;         /*输出埃及分数式*/
printf("NO%d:%d/%d=1/%d",n,m,d,a);
printf("+1/%d+1/%d+1/%d \n",b,c,e);
break;
}
}
printf("共上述%d个分数式\n",n);
}


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

确定分数m/d,请输入m,d:5,121
请确定分母的上届:1000
把分数5/121分解为4个埃及分数之和:
NO1:5/121=1/28+1/462+1/484+1/726
NO2:5/121=1/30+1/220+1/484+1/726
NO3:5/121=1/33+1/120+1/605+1/968
NO4:5/121=1/33+1/132+1/484+1/726
NO5:5/121=1/36+1/99+1/484+1/726
NO6:5/121=1/44+1/66+1/484+1/726
共上述6个分数式


注意:从以上6个分解式可知,把5/121分解为4个埃及分数之和,最优分母为726

以上两个程序并不限于关于5/121的分解,其他分数或整数(输入时分母d=1)的埃及分数式,请运行程序搜索;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息