同基因积式

来源:互联网 发布:csol大刀优化软件 编辑:程序博客网 时间:2024/05/02 04:57

在以上构建同基因和式的基础上本节更进一步,探讨涉及同基因数乘积的两类数式:同基因倍积式与同基因乘积式;


同基因倍积式

定义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.程序运行示例及其注意事项:

请输入位数:51:10035*3=301052:12375*3=371253:14247*3=42741······40:10899*9=9809141: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.程序运行示例及其注意事项:

请确定位数:51:1251*9=112592:141*84=118443:1481*8=11848······70:936*72=6739271:983*65=63895共有71个5位同基因乘积式

我们看到,同基因乘积式中“=”左边插入了一个乘号“*”,两边所含的数字完全相同,满足了“=”两边完全同基因的要求;

1 0