同基因积式

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


同基因倍积式

定义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位同基因乘积式

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值