总体思路:
高精度大数乘法 需要记录小数点位置 需要使用大数相乘 只是考验能否使用大数相乘
大整数乘法可以模拟乘法运算写 也可以使用分治写法 分治可以优化XY=AC2^N [(A-B)(D-C)+AC+BD]2^n/2+BD 时间复杂度可以优化到T(n) = O(n^log2(3) ) = O(n^1.59 )
有几个特判也需要注意,其他没什么
POJ使用to_string 过不了也不知道为啥必须手写 POJ使用stoi过不了也不知道为啥必须手写 POJ不能使用万能头文件 注意去除前后的0
另外java有大数类,可以直接得到结果
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
string BigNumberAccumulate(string a, string b)
{
int LenA = a.length();
int LenB = b.length();
if (LenB > LenA)
{
string temp = a;
a = b;
b = temp;
int tempLen = LenA;
LenA = LenB;
LenB = tempLen;
}
int D = LenA - LenB;
int JinZi = 0, i;
for (i = LenB - 1; i >= 0; i--)
{
int temp = (a[i + D] - '0') + (b[i] - '0') + JinZi;
JinZi = 0;
if (temp >= 10)
{
JinZi++;
temp -= 10;
}
a[i + D] = temp + '0';
}
while (i >= 0 - D && JinZi == 1)
{
int temp = (a[i + D] - '0') + JinZi;
JinZi = 0;
if (temp >= 10)
{
JinZi++;
temp -= 10;
}
a[i + D] = temp + '0';
i--;
}
if (JinZi == 1)
a = "1" + a;
while (a[0] == '0')
a = a.substr(1, a.length() - 1);
return a;
}
string Pointclear(string temp, int Pos)
{
if (Pos != -1)
return temp.erase(Pos, 1);
else
return temp;
}
string Tostring(int n)
{
string ret = "";
while (n)
{
ret += n % 10 + '0';
n /= 10;
}
reverse(ret.begin(), ret.end());
return ret;
}
int Stoi(string s)
{
int ret = 0;
for (int i = 0; i < s.length(); i++)
{
ret = ret * 10 + s[i] - '0';
}
return ret;
}
string D_ADD(string x, string y)
{
int LenX = x.length();
int LenY = y.length();
int o = max(LenX, LenY);
if (o <= 4)
return Tostring(Stoi(x) * Stoi(y));
if (o & 1)
o++;
int lenX = x.length();
int lenY = y.length();
for (lenY; lenY < o; lenY++)
y = "0" + y;
for (lenX; lenX < o; lenX++)
x = "0" + x;
int n = o / 2;
string AC = D_ADD(x.substr(0, n), y.substr(0, n));
string BD = D_ADD(x.substr(n, n), y.substr(n, n));
string AD = D_ADD(x.substr(0, n), y.substr(n, n));
string BC = D_ADD(x.substr(n, n), y.substr(0, n));
string AD_BC = BigNumberAccumulate(AD, BC);
AD_BC.resize(AD_BC.length() + n, '0');
AC.resize(AC.length() + o, '0');
string XY = BigNumberAccumulate(AC, BigNumberAccumulate(AD_BC, BD));
return XY;
}
int main()
{
string x;
int y;
while (cin >> x >> y)
{
int posX = x.find('.');
if (posX != -1)
{
while (x[x.length() - 1] == '0')
x = x.substr(0, x.length() - 1);
if(x[x.length() - 1] == '.')
x = x.substr(0, x.length() - 1);
x = Pointclear(x, posX);
string sum = x;
for (int i = 0; i < y - 1; i++)
{
string temp = D_ADD(sum, x);
sum = temp;
}
int len = x.length();
int lenSum = sum.length();
if ((len - posX) * y <= lenSum)
{
if (posX != -1)
{
int h = (lenSum - (len - posX) * y);
sum.insert(h, ".");
}
}
else
{
for (int i = lenSum; i < (len - 1) * y; i++)
sum = "0" + sum;
sum = "." + sum;
}
while ( sum[ sum.length() - 1] == '0')
sum = sum.substr(0, sum.length() - 1);
if( sum[ sum.length() - 1] == '.')
sum = sum.substr(0, sum.length() - 1);
cout << sum << endl;
}
}
|