题解 P1045 【麦森数】
zhouzihan_2004 · · 题解
裸的高精度题
1求位数:直接套用数学公式log10(2)乘上n就好了(c++中有log10函数)
2求后五百位:如果直接模拟高精度肯定会超时,所以要优化看见。其他人都是快速幂,这里提供一种时间较慢,但容易实现的方法:
对于2^n,可以分解成(2^x)^(n/x),这是本解题思路的核心,这样就不用运算n次,而是n/x次,只要2^x在范围内,就可以实现优化,可以通过本题。
不过要注意,因为c++中除法运算会自动向下取整(整型),所以还要多乘上一个2^(n%x)
最后,再把最后一位减一就可以了
代码如下:
#include<iostream>
#include<cmath>
#define x 50
using namespace std;
long long n,f[502],Pow[x+1],tmp;
double count;
void output()
{
count=log10(2)*n;//数学公式
while(count>1)
{
tmp++;
count--;
}
if(count) tmp++;//不是整数则向上取整
cout<<tmp<<endl;
for(int i=500;i>=1;i--)
{
cout<<f[i];
if(i%50==1) cout<<endl;
}
return ;
}
int main()
{
Pow[0]=1;
for(int i=1;i<=x;i++)
Pow[i]=Pow[i-1]*2;//Pow[i]:2的i次方
cin>>n;
f[1]++;
for(int i=1;i<=n/x;i++)
{
for(int j=1;j<=500;j++)
f[j]*=Pow[x];
for(int j=1;j<=500;j++)
if(f[j]>=10)
{
f[j+1]+=f[j]/10;
f[j]%=10;
}
f[501]=0;
}//高精度主体
for(int i=1;i<=x-1;i++)
if(n%x==i)
{
for(int j=1;j<=500;j++)
f[j]*=Pow[i];
for(int j=1;j<=500;j++)
if(f[j]>=10)
{
f[j+1]+=f[j]/10;
f[j]%=10;
}
f[501]=0;
}//乘上2的n%x次方 f[1]--;
output();
return 0;
}