关于这个乘法,重点就是公式的化简
使得子问题的规模减小
问题
求X*Y的值
思路
将X、Y分别分为两部分
即X=a10^n/2+b ,n为X的位数
Y=c10^m/2+d ,m为Y的位数
理想情况下m=n,那么
XY=ac10^n + bd+ (ad+bc)*10^n/2
(ad+bc)*10^n/2 =((a-b)(d-c)+ac+bd)*10^n/2
由此推广到XY位数不相等的情况
代码实现
包括位数相同与位数不同的情况
#include<stdio.h>
#include<string.h>
#include<math.h>
int sign(long A);
void samenumber();
void unsamenumber();
long long int jisuansame(long x,long y,int n);
long long int jisuanunsame(long x,long y,int xn,int yn);
int main()
{
samenumber();//相同位数
unsamenumber();//不同位数
return 0;
}
int sign(long A)//符号判断
{
if(A>0)
return 1;
else return -1;
}
void samenumber()
{
long x=0,y=0,sum=0;
int n=0;
printf("理想状态下用法:x=");
scanf("%d",&x);
printf("y=");
scanf("%d",&y);
printf("整数位数n=");
scanf("%d",&n);
sum=jisuansame(x,y,n);
printf("%d\n",sum);
}
long jisuansame(long x,long y,int n)//计算相同位数
{
int fuhao=sign(x)*sign(y);
x=labs(x);
y=labs(y);
if(x==0||y==0) return 0;
else if(n==1) return fuhao*x*y;
else
{
long a=(long)(x/pow(10,n/2));
long b=(x%(long)pow(10,n/2));
long c=(long)(y/pow(10,n/2));
long d=(y%(long)pow(10,n/2));
long ac=jisuansame(a,c,n/2);
long bd=jisuansame(b,d,n/2);
long abcd=jisuansame((a-b),(d-c),n/2)+ac+bd;
return (long)(fuhao*(ac*pow(10,n)+abcd*pow(10,n/2)+bd));
}
}
void unsamenumber()//不同位数
{
long long x,y,sum=0;
int xn,yn;
printf("不理想状态下用法:x=");
scanf("%lld",&x);
printf("y=");
scanf("%lld",&y);
printf("x整数位数xn=");
scanf("%d",&xn);
printf("y整数位数yn=");
scanf("%d",&yn);
sum=jisuanunsame(x,y,xn,yn);
printf("%lld",sum);
}
long long int jisuanunsame(long x,long y,int xn,int yn)//计算不同位数
{
int fuhao=sign(x)*sign(y);
x=labs(x);
y=labs(y);
if(x==0||y==0) return 0;
else if(xn==1||yn==1) return fuhao*x*y;
else
{
int xn0=xn/2,yn0=yn/2;
int xn1=xn-xn0,yn1=yn-yn0;
long a=x/pow(10,xn0);
long b=x%(long)pow(10,xn0);
long c=y/pow(10,yn0);
long d=y%(long)pow(10,yn0);
long ac=jisuanunsame(a,c,xn1,yn1);
long bd=jisuanunsame(b,d,xn0,yn0);
long abcd=jisuanunsame(a*pow(10,xn/2)-b,d-c*pow(10,yn0),xn1,yn1);
return (long long int)(fuhao*(2*ac*pow(10,(xn0+yn0))+abcd+2*bd));
}
}