标签:图片 main 思想 ber log and 展开 问题 class
将问题分为k个子问题,对这k个子问题分别求解。如果子问题的规模仍然不够小,则每个子问题再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。
这个问题的时间复杂度我似懂非懂,想知道其中的具体过程的请自行百度。
对于两个数字X、Y,传统计算方式的时间复杂度是O(n^2)
。
那么我们可以根据高位低位进行分隔,例如:
其中,xn0
、xn1
分别为A、B的位数,yn0
、yn1
同理。那么X*Y
可写成如下结果:
由于我们需要计算4次大整数乘积,所以算法复杂度依然时O(n^2)
。
为了减小时间复杂度,我们进行如下改动:
令:
展开可得:
综上可得:
现在我们将时间复杂度降低到了O(n^1.59)
。
#include<iostream>
#include<cmath>
typedef long long ll;
using namespace std;
void AcceptAndCompute();
int SizeNumber(ll num);
ll Compute(ll X, ll Y, int xn, int yn);
int Sign(ll x);
int main()
{
AcceptAndCompute();
return 0;
}
void AcceptAndCompute()
{
ll X, Y;
cout<<"输入X,Y的值:"<<endl;
cout<<"X: "; cin>>X;
cout<<"Y: "; cin>>Y;
cout<<"直接计算结果:"<<X*Y<<endl; // 直接运算
int xn, yn;
xn = SizeNumber(abs(X));
yn = SizeNumber(abs(Y));
int sign_x, sign_y;
sign_x = Sign(X);
sign_y = Sign(Y);
X = abs(X); Y = abs(Y);
cout<<"分治计算结果:"<<ll(Compute(X, Y, xn, yn)*sign_x*sign_y)<<endl;
}
int SizeNumber(ll num) // 计算num有多少位
{
return int(log10(num)) + 1;
}
int Sign(ll x) // 获取符号
{
return x > 0 ? 1 : -1;
}
ll Compute(ll X, ll Y, int xn, int yn)
{
if(!X || !Y) return 0;
if(xn == 1 || yn == 1) return X * Y;
int xn0 = xn / 2, yn0 = yn / 2;
int xn1 = xn - xn0, yn1 = yn - yn0;
ll A = ll(X / ll(pow(10, xn1)));
ll B = ll(X % ll(pow(10, xn1)));
ll C = ll(Y / ll(pow(10, yn1)));
ll D = ll(Y % ll(pow(10, yn1)));
ll AC = Compute(A, C, xn0, yn0);
ll BD = Compute(B, D, xn1, yn1);
ll ABCD = Compute(ll(A*pow(10,xn1)-B), ll(D-C*pow(10, yn1)), xn0, yn0);
return ll(2*AC*pow(10, (xn1+yn1))+ABCD+2*BD);
}
标签:图片 main 思想 ber log and 展开 问题 class
原文地址:https://www.cnblogs.com/xxmmqg/p/12807158.html