高精度算法于2020/7/24-25

今天补的是之前所看到的高精度算法。
主要从洛谷和杭电几条经典题目入手。
原理:因为long long乃至double能表示的范围有时候达不到题目所需要的范围。所以利用数组模拟大数的加减乘除。
首先感谢大佬详细的教学@Angel_Kitty

大佬的博客

我这篇就相当于学习大佬教学的心得吧

高精度加法

P1061

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int a[10050],b[10050],c[10050];
int lena,lenb,lenc;
char s1[10050],s2[10050];

int main()
{
    scanf("%s %s",s1+1,s2+1);
    lena=strlen(s1+1);
    lenb=strlen(s2+1);
    for(int i=1;i<=lena;i++) a[i]=s1[lena-i+1]-'0';
    for(int i=1;i<=lenb;i++) b[i]=s2[lenb-i+1]-'0';
    lenc=max(lena,lenb);
    for(int i=1;i<=lenc;i++){
        c[i]=c[i]+a[i]+b[i];
        c[i+1]=c[i]/10;
        c[i]=c[i]%10;
    }
    while(c[lenc+1]>0) lenc++;
    for(int i=lenc;i>0;i--) printf("%d",c[i]);
}

注意点:
1.在这段代码里面是把数倒着存储的,方便处理有进位的情况
2.然后就是普通的模拟

高精度乘法

P1303

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int a[10050],b[10050],c[10050];
int lena,lenb,lenc;
char s1[10050],s2[10050];
 
int main()
{
    scanf("%s %s",s1+1,s2+1);
    lena=strlen(s1+1);
    lenb=strlen(s2+1);
    for(int i=1;i<=lena;i++) a[i]=s1[lena-i+1]-'0';
    for(int i=1;i<=lenb;i++) b[i]=s2[lenb-i+1]-'0';
    lenc=lena+lenb-1;
    for(int i=1;i<=lena;i++){
    	for(int j=1;j<=lenb;j++){
    		c[i+j-1]+=a[i]*b[j];
    		c[i+j]+=c[i+j-1]/10;
    		c[i+j-1]%=10;
		}
	}
    while(c[lenc+1]>0) lenc++;
    while (c[lenc]==0&&lenc>1)lenc--;//判断位数
    for(int i=lenc;i>0;i--) printf("%d",c[i]);
}

注意的是:这和大佬的代码稍微有所不同在于判断位数,防止出现“000”之类的情况。

HDU1042

利用的是高精度乘以单精度

#include<iostream>
using namespace std;
void hanshu(int n)
{
	int digit=1;
	int carry;//进位 
	int j,temp;
	int a[500050]={1};
	for(int i=1;i<=n;i++)
	{
		
        for(carry = 0, j = 1; j <= digit; ++j) {
            temp = a[j - 1] * i + carry;
            a[j - 1] = temp % 10;
            carry = temp / 10;
        }
        while(carry) {
            a[++digit - 1] = carry % 10;
            carry /= 10;
        }
    
	}
	for(int k=digit-1;k>=0;k--)cout<<a[k];
}
int main()
{
	int n;
	while(cin>>n)
	{
		hanshu(n);
		cout<<endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值