高精度加减乘除及进制转换及压位

142 篇文章 0 订阅
73 篇文章 0 订阅

加法
原题 https://www.luogu.org/problemnew/show/P1601
题解

#include<bits/stdc++.h>
using namespace std;
char a1[1000],b1[1000];
int a[1000],b[1000],c[1000];
int main()
{
	memset(c,0,sizeof(c));//初始化 
	scanf("%s",a1);scanf("%s",b1);
	int lena=strlen(a1),lenb=strlen(b1);
	for(int i=0;i<lena;i++) {a[lena-i-1]=int(a1[i]-48);} 
	 for(int i=0;i<lenb;i++) {b[lenb-i-1]=int(b1[i]-48);//倒序处理便于进位 }
	int m=max(lena,lenb);
	for(int i=0;i<m;i++)
	{
		c[i]+=a[i]+b[i];
		while(c[i]>=10)	{c[i+1]++;c[i]=c[i]-10;}
	}
	while(c[m]==0&&m!=0) m--;//避免0+0时不输出 
	for(int i=m;i>=0;i--) cout<<c[i];
	cout<<endl;
	return 0;
}

在这里插入图片描述
减法
原题 https://www.luogu.org/problemnew/show/P2142
题解

#include<bits/stdc++.h>
using namespace std;
int main()
{
	string a,b;//求长度要用a.length() b.length() 
	int aa[1000001]={0};
	int bb[1000001]={0};
	int cc[1000001]={0};
	int i,j,lena,lenb,lenc;
	cin>>a>>b;
	lena=a.length();lenb=b.length();
	//默认aa是大数 
	memset(aa,0,sizeof(aa));memset(bb,0,sizeof(bb));memset(cc,0,sizeof(cc));
	if((lena<lenb)||(lena==lenb&&a<b)) {swap(a,b);swap(lena,lenb);cout<<'-';}//位数相等才能比较字典序 ,交换之后位数也要跟着变化 
//	cout<<lena<<" "<<lenb<<"**";
	for(i=0;i<lena;i++) aa[lena-i-1]=a[i]-48;//必须进行倒序处理以方便借位 
    for(i=0;i<lenb;i++) bb[lenb-i-1]=b[i]-48;
    //cout<<aa<<"\n"<<bb;
    //printf("%s\n",aa);printf("%s\n",bb);
   // for(i=0;i<lena;i++) cout<<aa[i];
   // for(i=0;i<lenb;i++) cout<<bb[i];
    lenc=max(lena,lenb);

	for(i=0;i<lenc;i++)	
	{
		if(aa[i]<bb[i]) {aa[i+1]--;cc[i]=aa[i]+10-bb[i];}
		else cc[i]=aa[i]-bb[i];
	}
	
	while(cc[lenc-1]==0&&lenc!=1) lenc--;
	
	for(i=lenc-1;i>=0;i--) cout<<cc[i];
	cout<<endl;
	return 0;
	
}

在这里插入图片描述

乘法
乘法要增位
原题 https://www.luogu.org/problemnew/show/P1303
题解

#include<bits/stdc++.h>
using namespace std;
char a1[50001],b1[50001];
int a[50001],b[50001],i,x,len,j,c[50001];
int main()
{
	cin>>a1>>b1;
	a[0]=strlen(a1);b[0]=strlen(b1);
	for(i=1;i<=a[0];i++) a[i]=a1[a[0]-i]-48;//处理成倒序便于处理 
	for(i=1;i<=a[0];i++) b[i]=b1[b[0]-i]-48;
	for(i=1;i<=a[0];i++)
	    for(j=1;j<=b[0];j++)
	        c[i+j-1]+=a[i]*b[j];
    len=a[0]+b[0];
    for(i=1;i<len;i++)
        if(c[i]>=10)
        {
            c[i+1]+=c[i]/10;c[i]%=10;
	    }
	while(c[len]==0&&len>1) len--;//处理多余的0和保护唯一的0
	for(i=len;i>=1;i--) cout<<c[i];
	cout<<endl;
	return 0; 
}

在这里插入图片描述
进制转换
原题 https://www.luogu.org/problemnew/show/P1604

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a[2010],b[2010],c[2018],i,y,x,l1,l2,z;
	char n[2001],m[2001];
	cin>>z;
	cin>>n;cin>>m;
	//在主程序内定义的变量,必须要有初始化 
	memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));
	l1=strlen(n);l2=strlen(m);
	for(i=0;i<l1;i++)
	    if(z>10&&n[i]>='A') a[l1-i]=n[i]-'A'+10;//处理达大于10的进制
		else a[l1-i]=n[i]-'0';
	 for(i=0;i<l2;i++)
	    if(z>10&&m[i]>='A') b[l2-i]=m[i]-'A'+10;//处理达大于10的进制
		else b[l2-i]=m[i]-'0';
		x=0;y=0;//必须要进行初始化 
	while(x<=l1||x<=l2){
		x++;//x是位数,y是进位 
		c[x]=y+a[x]+b[x];
		y=c[x]/z;
		c[x]%=z;
	}
	while(c[x]==0&&x>1) x--;
	for(i=x;i>=1;i--){
	    if(c[i]<10) cout<<c[i];
	    else cout<<(char)(c[i]-10+'A');
		}
//	 cout<<endl;
	 return 0;
}

在这里插入图片描述
压位
原题 https://www.luogu.org/problemnew/show/P1255

#include<bits/stdc++.h>
using namespace std;
int n,i,ans[5001][1000]={{1,0},{1,1},{1,2}};//对前三行初始化,每行第0列是长度,f0=0,f1=1;f2=2; 
                                           //ans数组中,每行代表一个数 
int main()
{
	cin>>n;
	for(i=3;i<=n;i++)
	{
		ans[i][0]=ans[i-1][0];//继承上一个数的长度 
		int x=0;
		for(int j=1;j<=ans[i-1][0];j++)
		{//每一行的第0列存储该数的长度 
		    ans[i][j]=ans[i-1][j]+ans[i-2][j]+x;
			x=ans[i][j]/10000;//x是进位 
			ans[i][j]%=10000;//压位:将原来的10进制变为10000进制,使计算时间变为原来的1/3 
        } 
		while(x) 
		{
		    ans[i][++ans[i][0]]=x%10000;
			x/=10000;
		}
	}
	printf("%d",ans[n][ans[n][0]]);//第一位不用处理0的问题 
	for(i=ans[n][0]-1;i;i--) printf("%04d",ans[n][i]);//每次输出4位,左侧用0填充 
	return 0;
}

在这里插入图片描述

乘法、除法、大小比较
注意 除法要去零
原题 https://www.luogu.org/problemnew/show/P1080
题解
https://blog.csdn.net/qq_38993096/article/details/87308650

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值