总之就是 | 高精度丨Pt.One
2021.2.6修改:
统一了题解的题目格式
这个是一个做题记录+题解,看题解可以直接往后翻
昨天学了高精度之后就开始练题,但没想到这个看起来这么简单的题居然废了我一个半小时
先看题
题目描述
任意给定一个正整数N(N≤100),计算2的n次方的值。
输入
输入一个正整数N。
输出
输出2的N次方的值。
输入样例
5
输出样例
32
非常简单的感觉,但是作为一个高精度的题,自然有坑:
“正整数N(N≤100),计算2的n次方的值 ”
2的100次方,unsigned long long也放不下了 (O x O)
于是必须要用高精度算法来模拟次方计算的过程了
解法
非正经想法,可以不看
(不过我还是先用来最朴实的int long long试了试测试点)
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int long long n;cin>>n;
long long d=(pow(2,n));
cout<<d;
return 0;
}
(当然还是有能过的,Nice)
正经解法
思路
实际上最一开始大脑还是挺空白的
但是结合昨天高精度的学习
我可以大约得出以下的解题方法
- 将数据按照数位拆分
- 用算法模拟运算的过程
那么我开始着眼于观察2的次方有肾么事儿
二的一次方:2
二的二次方:4
二的三次方:8
二的四次方:16
二的五次方:32
二的六次方:64
把后三个拿出来看:
| 初始数 | 个位 | 十位 | 最终数 |
| ---- | ---- | ---- | ---- | ---- |
| 16 | 62=12(进1)->2 | 12+1 ->3 | 32 |
| 32 | 22=4 | 32=6 | 64 |
于是乎,我得出了模拟算法:
计算二的N次方,把每个位上的数*2再考虑进位就可以了
这里的代码实现就是
for(int i=0;i<n;i++)
{
for(int p=50;p>0;p--)
{
int k=a[p]*2+r;
r=k/10;
a[p]=k%10;
}
}//我这里是从右往左
最后全部的代码就是
#include <iostream>
using namespace std;
int a[51];
int main()
{
int n,r=0,len=0;cin>>n;a[50]=1;
for(int i=0;i<n;i++)
{
for(int p=50;p>0;p--)
{
int k=a[p]*2+r;
r=k/10;
a[p]=k%10;
}
}
while(a[len]==0)
{
len++;
}
for(int i=len;i<51;i++)
{
cout<<a[i];
}
cout<<endl;
return 0;
}
反思与总结
这里属于笔记部分,题解已经结束了
今天的最初的错解还是错的,现在还不知道怎么改......
放在这里,以后改吧()
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[51],n,len,r;
void text()
{
for(int u=1;u<=50;u++)
{
cout<<a[u];
}cout<<endl;
cout<<"r="<<r<<endl;
}
void m2()
{
r=0;a[1]=1;len=1;
for(int i=1;i<=n;i++)
{
for(int p=1;p<=len;p++)
{
a[p]=a[p]*2;
if(a[p]>=10)
{
r=1;
a[p+1]+=r;
a[p]-=10;
}
text();
}
if(i%3==0)
len++;
}
}
int main()
{
cin>>n;
m2();
int u=50;
while(a[u]==0)
{
u--;
}
for(int e=u;e>=1;e--)
cout<<a[e];
cout<<endl;
return 0;
}
具体问题应该就是核心部分的循环出了问题,但是并不是很清楚怎么改
End
2021.1.29
暂无字数统计
Do you like WHAT YOU SEE ?