在以上构建同基因和式的基础上本节更进一步,探讨涉及同基因数乘积的两类数式:同基因倍积式与同基因乘积式;
同基因倍积式
定义n位同基因倍积式:若n位整数u的k(2<=k)倍s=u*k与u同基因,则称u*k=s为一个n位同基因倍积式;
例如,1359*7=9513是一个4位同基因倍积式,10449*9=94041是一个5位同基因倍积式;
同时为了避免出现类似13590*7=95130的衍生现象,要求同基因倍积式u*k=s中u的个位数字不能为数字“0”;
输入整数n(2<=n<=9),搜索并输出所有n位同基因倍积式;
1.设计要点:
设置f、h数组存储式中n位整数u、s的各个数字的频数,便于比较是否同基因;
若k>=10,积s=u*k比u多一位,不可能同基因,显然倍数k满足:1< k< 10;
设置k(2~9)与u(t~(10*t-1)/k)二重循环,确保u与倍积s=u*k均为n位整数;
若u的个位数字为“0”,返回;
分离u、s并用f、g数组统计其数字频数,检测同基因与上面相同;
2.程序设计:
#include<stdio.h>
int main()
{
int b,c,j,k,n,f[10],h[10];
long d1,d3,t,s,u,w;
printf("请输入位数:");
scanf("%d",&n);
w=0;
for(t=1,k=1;k<=n-1;k++)
t=t*10; /*计算最小的n位整数t*/
for(k=2;k<=9;k++)
for(u=t;u<=(10*t-1)/k;u++) /*枚举n位加数u*/
{
if(u%10==0)
continue; /*消除衍生现象*/
s=k*u;
d1=u;
d3=s;
b=0;
for(j=0;j<=9;j++)
f[j]=h[j]=0;
for(j=1;j<=n;j++) /*分离并统计u、s的各个数字*/
{
c=d1%10;
f[c]++;
d1=d1/10;
c=d3%10;
h[c]++;
d3=d3/10;
}
for(j=0;j<=9;j++) /*检验积u、s是否同基因*/
if(f[j]!=h[j])
{
b=1;
break;
}
if(b==0)
{
w++;
printf("%3d:%ld*%ld=%ld \n",w,u,k,s);
}
}
printf("共有%ld个%d位同基因倍积式 \n",w,n);
}
3.程序运行示例及其注意事项:
请输入位数:5
1:10035*3=30105
2:12375*3=37125
3:14247*3=42741
······
40:10899*9=98091
41:10989*9=98901
共有41个5位同基因倍积式
显然,当倍数k=2时的同基因倍积式是同基因和式中的“两加数相同”的子集;
不难发现,以上同基因倍积式的“=”的两边并不同基因(因等号左边多了乘数k),下面探讨的同基因乘积式的“=”两边完全同基因;
同基因乘积式
定义n位同基因乘积式:在一个n位整数m的数字间插入一个乘号“*”把整数m分割成前后两个整数v、u,若乘积s=v*u与m同基因,则乘积式v*u=s(约定u<=v)称为一个n位同基因乘积式;
注意到86*8=688、8*86=688都是3位同基因乘积式,这两个式中两个乘数只是顺序不同,严格说只能算一个3位同基因乘积式,为避免重复统计,因此约定:v>=u;
同时为了消除一个n位同基因乘积式的乘数u或v的尾部加一个“0”后成为n+1位同基因乘积式的近亲衍生现象(例如860*8=6880、86*80=6880),要求同基因乘积式v*u=s中u、v的个位数字都不能为“0”;
对于给定的整数n(2<=n<=9),搜索并输出所有n位同基因乘积式;
1.设计要点:
设置f、h数组存储式中n位整数m与乘积s的各个数字的频数,便于比较是否同基因;
(1)、枚举循环设置;
通过循环计算最小的n位整数t,设置n位整数m(t~10*t-1)的枚举循环;
若m的个位数字为“0”,因而导致后段数u个位数字为“0”,则返回;
分离并用数组f统计m的各个数字,f[j](j:0~9)即数字j的个数;
(2)、插入“*”的实现;
注意到约定v>=u的前提下,n位整数有k=n/2个插入“*”的方式,因而设置k(1~n/2)循环,应用中间变量e=10^k,把整数m分割出整数u、v,并计算乘积s=u*v;
若乘积s不为n位,或v< u,或v%10==0,显然不符合要求,则返回;
(3)、检测同基因;
对乘积s(赋值给d,以保证分解数字时s不变),通过n次循环分离其n个数字c,并用数组h统计数字c的频数;
在j(0~9)循环中比较f、h数组的值,若f[j]!=h[j],说明s与m中至少有一个数字不同,不是同基因,返回;
若s与m是同基因,则输出一个n位同基因乘积式v*u=s,用w统计个数;
2.程序设计:
#include<stdio.h>
int main()
{
int b,c,j,k,w,n,f[10],h[10];
long e,m,s,d,t,u,v;
printf("请确定位数:");
scanf("%d",&n);
w=0;
for(t=1,k=1;k<=n-1;k++)
t*=10; /*计算最小的n位整数t*/
for(m=t;m<10*t;m++) /*枚举所有n位数*/
{
if(m%10==0)
continue; /*首先排除u的个位数字为0*/
d=m;
for(j=0;j<=9;j++)
f[j]=0;
for(j=1;j<=n;j++)
{
c=d%10;
f[c]++;
d=d/10;
}
for(e=1,k=1;k<=n/2;k++) /*选用右边n/2个插入乘号*/
{
b=0;
e=e*10;
u=m%e;
v=m/e;
s=u*v;
if(s<t || s>=10*t || v%10==0 || v<u)
continue; /*排除不符同基因乘积式*/
d=s;
for(j=0;j<=9;j++)
h[j]=0;
for(j=1;j<=n;j++)
{
c=d%10;
h[c]++;
d=d/10;
}
for(j=0;j<=9;j++) /*检验积s与m是否基因*/
if(f[j]!=h[j])
{
b=1;
break;
}
if(b==0)
{
w++;
printf("%d:%ld*%ld=%ld \n",w,v,u,s);
}
}
}
printf("共有%d个%d位同基因乘积式 \n",w,n);
}
3.程序运行示例及其注意事项:
请确定位数:5
1:1251*9=11259
2:141*84=11844
3:1481*8=11848
······
70:936*72=67392
71:983*65=63895
共有71个5位同基因乘积式
我们看到,同基因乘积式中“=”左边插入了一个乘号“*”,两边所含的数字完全相同,满足了“=”两边完全同基因的要求;