如果两组由不同的n(n>=3)个正整数组成的数组中,两数组的各个数之和相等,且两数组的各个数从2次幂之和、3次幂之和以至到n-1次幂之和均相等,则这两个数组称为等幂和n元组;
本节从探讨等幂和3元组至等幂和n(n<=6)元组,其中递推关系的建立与实施是重点,也是难点;
等幂和3元组
把6个互不相等的正整数a、b、c、d、e、f分成两组,若这两个数组具有以下两个相等特性:
a+b+c=d+e+f=s
a^2+b^2+c^2=d^2+e^2+f^2=s2
则把这两数组(a、b、c)与(d、e、f)(约定a< b< c,d< e< f,a< d)称为等幂和3元组;
例如(1,5,6)与(2,3,7)就是等幂和3元组:
1+5+6=2+3+7=12
1^2+5^2+6^2=2^2+3^2+7^2=62
给定正整数s,探求和为s的所有等幂和3元组;
1.说明:
设6个正整数存储于b数组b(1),……,b(6)中,同时约定: b(1)、b(2)、b(3)为一组,b(4)、b(5)、b(6)为另一组;
从键盘输入整数s,因6个不同正整数之和至少为21,即输入整数s>=11;
设置b(1)、b(2)与b(4)、b(5)循环,注意到b(1)+b(2)+b(3)=s,且b(1)< b(2)< b(3),因而b(1),b(2)循环取值为:
b(1):1~(s-3)/3,因为b(2)比b(1)至少大2;
b(2):b(1)+1~(s-b(1)-1)/2,因为b(3)比b(2)至少大1;
b(3)=s-b(1)-b(2);
设置b(4),b(5)循环基本同上,只是b(4)>b(1),因而b(4)起点为b(1)+1;
设 s2=b(1)*b(1)+b(2)*b(2)+b(3)*b(3),如果b(4)*b(4)+b(5)*b(5)+b(6)!=s2,则继续探索;
同时注意到两个3元组中若部分相同部分不同,不可能有和与平方和同时相等,因而可省略排除以上6个正整数中是否存在相等的检测;
若满足平方和相等要求,打印输出和为s的等幂和3元组,并用n统计解的个数;
2.程序设计:
#include<stdio.h>
#include<math.h>
int main()
{
int n,s,s2,b[7];
printf("请输入正整数s:");
scanf("%d",&s);
n=0;
for(b[1]=1;b[1]<=(s-3)/3;b[1]++) /*设置枚举循环*/
for(b[2]=b[1]+1;b[2]<=(s-b[1]-1)/2;b[2]++)
for(b[4]=b[1]+1;b[4]<=(s-3)/3;b[4]++)
for(b[5]=b[4]+1;b[5]<=(s-b[4]-1)/2;b[5]++)
{
b[3]=s-b[1]-b[2];
b[6]=s-b[4]-b[5]; /*确保和等于s*/
s2=b[1]*b[1]+b[2]*b[2]+b[3]*b[3];
if(b[4]*b[4]+b[5]*b[5]+b[6]*b[6]!=s2)
continue; /*排除平方和不相等*/
n++;
printf("%3d: (%2d,%2d,%2d) ",n,b[1],b[2],b[3]);
printf("(%2d,%2d,%2d) s2=%ld \n",b[4],b[5],b[6],s2);
}
if(n==0)
printf("无解!\n");
}
3.程序运行示例及其注意事项:
请输入正整数s:15
1: ( 1, 6, 8) ( 2, 4, 9) s2=101
2: ( 2, 6, 7) ( 3, 4, 8) s2=89
运行程序不难得数组元素均为1位数的等幂和3元组有4组:
- (1,5,6;2,3,7),(1,6,8;2,4,9),(2,6,7;3,4,8),(3,7,8;4,5,9)
可以把以上4组解巧妙重组为“4位数”3元组:
- (1123,5667,6878;2234,3445,7989)(s1=13668,s2=80682902)
以上“4位数”3元组称为金蝉数组,因该数组具有和相等(s1)且平方和也相等(s2),还具有神奇的脱壳性质:
同时从高位去除1、2个数字,或同时从低位去除1、2个数字,或同时去除最高位与最低位后,分别得:
(123,667,878;234,445,989)(s1=1668,s2=1230902)
(23,67,78;34,45,89)(s1=168,s2=11102)
(112,566,687;223,344,798)(s1=1365,s2=804869)
(11,56,68;22,34,79)(s1=135,s2=7881)
(12,66,87;23,44,98)(s1=165,s2=12069)
经过脱壳而得的以上数组均 具有和相等(s1)且平方和也相等(s2) 的特性;
等幂和n元组
再看“1,5,8,12”与“2,3,10,11”这两个4元数组具有以下特性:
1+5+8+12=2+3+10+11=26
1^2+5^2+8^2+12^2=2^2+3^2+10^2+11^2=234
1^3+5^3+8^3+12^3=2^3+3^3+10^3+11^3=2366
显然,“1,5,8,12”与“2,3,10,11”为等幂和4元组;
这些奇特的数组是如何得到的呢?
以此类推,是否存在等幂和5元组或等幂和6元组?
下面设计探索等幂和n(3<=n<=6)元组;
1.说明:
首先给出以下一个递推性质,它是求解的依据:设a数组(a1,a2,……,an)与b数组(b1,b2,……,bn)的一次幂和相等,……,k-1次幂和也相等,则可以应用二项式定理证明一下的递推性质:
(1)、当k为奇数时:
- a1^k+……+an^k+(m-a1)^k+……+(m-an)^k=b1^k+……+bn^k+(m-b1)^k+……+(m-bn)^k;
(2)、当k为偶数时:
- a1^k+……+an^k+(m-b1)^k+……+(m-bn)^k=b1^k+……+bn^k+(m-a1)^k+……+(m-an)^k;
应用上述递推性质,先取互不相同的正整数a1、a2、b1、b2,使得a1+a2=b1+b2,然后取k=2,通过由小到大取值逐个试验确定整数m,代入偶数递推式后使等式的两边出现一个相同项,消去该项后则得到两个3元数组(a1,a2,a3)与(b1,b2,b3),其和相等,平方和也相等;
例如,a1+a2=b1+b2取为1+6=3+4,m=8,据偶数递推式则有:
- 1^2+6^2+(8-3)^2+(8-4)^2=3^2+4^2+(8-1)^2+(8-6)^2
即有:
- 1^2+6^2+5^2+4^2=3^2+4^2+7^2+2^2
化简得:
- 1^2+6^2+5^2=3^2+7^2+2^2
即得两个和相等(都为12)且平方和也相等(都为62)的两个3元数组:1,5,6与2,3,7;
接着又通过取值试验确定整数m代入奇数递推式后使等式两边出现两个相同项,消去后则得到两个4元数组(a1,a2,a3,a4)与(b1,b2,b3,b4),它们的和,平方和,立方和都相等;
以此类推,可得等幂和6元组;
2.程序设计:
#include<stdio.h>
#include<math.h>
int main()
{
int a1,b1,b2,n,k,m1,m,i,j,t,x,z;
int a[20],b[20],c[20],d[20],fa[20],fb[20];
long s1,s2,tt1[20],tt2[20],s[20];
printf("请输入每组数的个数n(2<n<7):");
scanf("%d",&n);
for(a1=1;a1<=19;a1++)
{
c[1]=a1;a[1]=a1;
for(b1=a1+1;b1<=22;b1++)
{
d[1]=b1;
b[1]=b1;
for(b2=b1+1;b2<=25;b2++) /*取初值a(1)+a(2)=b(1)+b(2)*/
{
d[2]=b2;
b[2]=b2;
c[2]=d[1]+d[2]-c[1];
a[2]=c[2];
for(k=2;k<=n-1;k++)
{
m1=a[k]+1;
if(b[k]>a[k])
m1=b[k]+1;
for(m=m1;m<=3*m1;m++) /*m在约定的循环中取值*/
{
for(i=1;i<=k;i++)
{
a[i]=c[i];
b[i]=d[i];
}
if(k%2==0) /*k为偶数按式(2)赋值*/
for(i=1;i<=k;i++)
{
a[k+i]=m-b[i];
b[k+i]=m-a[i];
}
else /*k为奇数按式(1)赋值*/
for(i=1;i<=k;i++)
{
a[k+i]=m-a[i];
b[k+i]=m-b[i];
}
t=0;
for(i=1;i<=2*k;i++)
for(j=1;j<=2*k;j++)
if(a[i]==b[j] && a[i]>0) /*比较两数组,相同的非零项赋*/
{
a[i]=0;
b[j]=0;
t=t+1;
break;
}
if(t!=k-1)
continue;
for(i=1;i<=2*k-1;i++) /*两数组分别由小到大排序*/
for(j=i+1;j<=2*k;j++)
{
if(a[i]>a[j])
{
x=a[i];
a[i]=a[j];
a[j]=x;
}
if(b[i]>b[j])
{
x=b[i];
b[i]=b[j];
b[j]=x;
}
}
for(i=1;i<=k+1;i++)
{
a[i]=a[i+k]; /*重新赋值,去除两数组中的零项*/
b[i]=b[i+k];
}
for(i=1;i<=k;i++)
{
if(z=0,a[i]==a[i+1] || b[i]==b[i+1]) /*同数组中有相同项返回*/
{
z=1;
break;
}
}
if(z==1)
continue;
for(i=1;i<=k+1;i++)
{
c[i]=a[i];
d[i]=b[i];
}
m=3*m1;
}
}
if(k!=n)
continue;
for(i=1;i<=n;i++)
{
tt1[i]=1;
tt2[i]=1;
}
for(i=1;i<=n;i++)
{
fa[i]=a[i];
fb[i]=b[i];
}
for(k=1;k<=n-1;k++)
{
for(s1=0,s2=0,i=1;i<=n;i++) /*验证两组各方幂和是否相等*/
{
tt1[i]=tt1[i]*fa[i];
tt2[i]=tt2[i]*fb[i];
s1=s1+tt1[i];
s2=s2+tt2[i];
}
z=0;
if(s1!=s2)
{
z=1;
break;
}
s[k]=s1;
}
if(z==1)
continue;
printf("\n第1组%d个数为:",n);
for(i=1;i<=n;i++)
printf("%d",a[i]);
printf("\n第2组%d个数为:",n);
for(i=1;i<=n;i++)
printf("%d",b[i]);
for(k=1;k<=n-1;k++)
printf("\n%d次方和都是: %ld",k,s[k]);
printf("\n");
if(z==0)
break;
}
if(z==0)
break;
}
if(z==0)
break;
}
}
3.程序运行示例及其注意事项:
输入每组数的个数n(2<n<7):6
第1组6个数为: 1 6 7 17 18 23
第2组6个数为: 2 3 11 13 21 22
1次方和都是:72
2次方和都是:1228
3次方和都是:23472
4次方和都是:472036
5次方和都是:970352
注意:运行程序,分别输入n=3、4、5,可得相应的等幂和3、4、5元组;
当n>6时,如何修改程序搜索等幂和n元组,请有兴趣的读者进一步探索;

本文介绍了等幂和数组的概念,特别关注等幂和3元组,通过递推关系探讨了从3元组到6元组的构造方法。程序设计用于寻找和为s的等幂和3元组,举例展示了递推性质的应用,并提出进一步探索等幂和n元组的方法。
1123

被折叠的 条评论
为什么被折叠?



