目录
题目:
题目描述:
题目链接:
思路:
核心思路:
高精度乘法
思路详解:
如果不了解高精度相关的算法,可以先搜索学习一下,后续有时间我会发高精度算法的整理
题目输入n和浮点数d,题目提示了浮点数视为字符串形式的长度,即把浮点数以字符串形式存到数组里。浮点数要乘以2^n,而n最大为1000,2^1000显然是个大整数,一开始我的想法是两个大整数的高精度乘法。但是for循环出2^n后不知道该怎么把这个数存入数组。
看完题解后发现其实可以转化为浮点数乘2的简单高精度乘法模板,然后循环这个乘法函数n次。然后对于小数点这个问题,看到的题解基本都是去掉然后再定义一个变量记录小数点的位置。但是其实一个小数乘2^n后小数位数是不会变化的,只有整数的位数会变化,所以我小数点也存进了数组。存了小数点,在进入mul函数,四舍五入,及最后的输出就要对小数点进行相应的特判处理
代码:
代码详解:
#include<bits/stdc++.h> //万能头文件
using namespace std;
vector<int> mul(vector<int> &D)
{
vector<int> C;
int t=0; //定义一开始的进位为0
for(int i=0;i<D.size();i++)
{
if(D[i]!='.')
{
t+=D[i]*2; //这一块都是高精度乘法的模板内容
C.push_back(t%10);
t/=10;
}
else
{
C.push_back(D[i]); //遇到小数点不做任何操作把小数点存进去
}
}
if(t!=0) //判断最高位是否有进位
{
C.push_back(t%10);
}
return C;
}
int main()
{
int n;
string d;
cin>>n>>d;
vector<int> D;
for(int i=d.size()-1;i>=0;i--) //将字符串d逆序存储到D中
{
if(d[i]!='.') //如果不是小数点就转换为数字放入数组
{
D.push_back(d[i]-'0');
}
else
{
D.push_back(d[i]); //如果是小数点就直接把小数点放入数组
}
}
vector<int> C=mul(D); //第一次对D做高精度乘法并把答案记录到C中
for(int i=0;i<n-1;i++)
{
C=mul(C); //剩下n-1次对C自身进行高精度乘法
}
for(int i=0;i<C.size();i++) //这里是把结果四舍五入为整数
{
if(C[i]=='.'&&C[i-1]>=5) //假设结果为1234.56那么现在C数组中存放的是65.4321,顺序从左往右
{
C[i+1]+=1; //如果顺序遍历到小数点,且小数点左一位大于等于5,则小数点右一位进1
}
}
for(int i=C.size()-1;i>=0;i--) //最后因为是逆序存储,所以也逆序输出
{
if(C[i]!='.')
{
printf("%d",C[i]);
}
else
{
break; //逆序输出只要输出到小数点就直接退出循环
}
}
return 0;
}
//题解:
//题目输入n和浮点数d,题目提示了浮点数视为字符串形式的长度,即把浮点数以字符串形式存到数组里
//浮点数要乘以2^n,而n最大为1000,2^1000显然是个大整数,一开始我的想法是两个大整数的高精度乘法
//但是for循环出2^n后不知道该怎么把这个数存入数组
//看完题解后发现其实可以转化为浮点数乘2的简单高精度乘法模板,然后循环这个乘法函数n次
//然后对于小数点这个问题,看到的题解基本都是去掉然后再定义一个变量记录小数点的位置
//但是其实一个小数乘2^n后小数位数是不会变化的,只有整数的位数会变化,所以我小数点也存进了数组
//存了小数点,在进入mul函数,四舍五入,及最后的输出就要对小数点进行相应的特判处理