总之就是 | 高精度丨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
暂无字数统计

posted @ 2021-01-29 13:49  HerikoDeltana  阅读(97)  评论(0编辑  收藏  举报