彩虹求助,高精度哪里错了
查看原帖
彩虹求助,高精度哪里错了
940854
Jianbing_Juan楼主2023/7/22 01:10

P1932

彩虹(指测试点信息)

我这些代码是自己研究出的,可能效率很低。但我主要想问我的代码逻辑思路哪里错了。应该是代码中的高精度减法函数错了,因为每个点都是line 2挂掉了。

下面是源代码,注释已写好。

#include <iostream>
#include <typeinfo>
#include <string>
using namespace std;

inline int gjd_cmp(string a,string b)//a>b:return 1   a==b:return 0   a<b:return -1
{//比较大小,不解释 
	string num1(a),num2(b);
	while(num1[0]=='0' and num1.length()-1)
	{
		num1.erase(0,1);
	}
	while(num2[0]=='0' and num2.length()-1)
	{
		num2.erase(0,1);
	}
	if(num1.length()<num2.length())
	{
		return -1;
	}
	if(num1.length()>num2.length())
	{
		return 1;
	}
	for(int i=0,l=num1.length();i<l;i++)
	{
		if(num1[i]>num2[i])
		{
			return 1;
		}
		if(num1[i]<num2[i])
		{
			return -1;
		}
	}
	return 0;
}

inline string gjd_add(string a,string b)
{
	int sum=0;
	string num1(a),num2(b),ans;
	if(num1.length()>num2.length())//补全位数 
	{
		num2.insert(0,num1.length()-num2.length(),'0');
	}
	else
	{
		num1.insert(0,num2.length()-num1.length(),'0');
	}
	for(int i=num1.length()-1;i>=0;i--)
	{
		sum+=num1[i]+num2[i]-2*'0';
		ans.insert(0,1,sum%10+'0');//进位 
		sum/=10;
	}
	if(sum)ans.insert(0,1,sum+'0');
	return ans;
}

inline string gjd_sub(string a,string b)//有去除前导零 
{
	int jw=0,op=0;
	string num1,num2,ans;//num1>num2
	if(gjd_cmp(a,b)>=0)num1=a,num2=b;
	else num1=b,num2=a,op=1;
	for(int i=num1.length()-1;i>=0;i--)
	{
		if(num1[i]<num2[i]+jw)
		{
			ans.insert(0,1,num1[i]+10-num2[i]-jw+'0');//借位 
			jw=1;
		}
		else
		{
			ans.insert(0,1,num1[i]-num2[i]-jw+'0');
			jw=0;
		}
	}
	while((ans[0]=='0')&&(ans.length()-1))
	{
		ans.erase(0,1);
	}
	if(op)ans.insert(0,1,'-');
	return ans;
}

inline string gjd_sub1(string a,string b)//string长度不变,不去除前导 0 
{
	int jw=0,op=0;
	string num1,num2,ans;//num1>num2
	if(gjd_cmp(a,b)>=0)num1=a,num2=b;
	else num1=b,num2=a,op=1;
	num2.insert(0,num1.length()-num2.length(),'0');
	for(int i=num1.length()-1;i>=0;i--)
	{
		if(num1[i]<num2[i]+jw)
		{
			ans.insert(0,1,num1[i]+10-num2[i]-jw+'0');
			jw=1;
		}
		else
		{
			ans.insert(0,1,num1[i]-num2[i]-jw+'0');
			jw=0;
		}
	}
	if(op)ans.insert(0,1,'-');
	return ans;
}

inline string gjd_mul(string a,string b)
{
	long long la=a.length(),lb=b.length();
	long long ia[la+50]={0},ib[lb+50]={0},ic[la+lb+100]={0};
	
	string ans;
	//num1.length()>num2.length()
	for(int i=la-1;i>-1;i--)
	{
		ia[i]=a[la-i-1]-'0';
	}
	for(int i=lb-1;i>-1;i--)
	{
		ib[i]=b[lb-i-1]-'0';
	}
	int sum=0,w=0;
	for(int i=0;i<la;i++)
	{
		for(int j=0;j<lb;j++)
		{
			ic[i+j]+=ia[i]*ib[j];
		}
	}
	for(int i=0;i<la+lb;i++)
	{
		ic[i+1]+=ic[i]/10;
		ans.insert(0,1,ic[i]%10+'0');
	}
	while((ans[0]=='0')&&(ans.length()-1))
	{
		ans.erase(0,1);
	}
	return ans;
}

inline string gjd_div(string a,string b)
{
	string ans,tmp(a);
	if(gjd_cmp(a,b)==-1)return "0";
	if(gjd_cmp(a,b)==0)return "1";
	//a>b
	for(int i=b.length();i<=a.length();i++)
	{
		if(gjd_cmp(tmp.substr(0,i),b)==-1)
		{
			ans.push_back('0');
		}
		else
		{
			for(int j=9;j>0;j--)
			{
				
				if(gjd_cmp(tmp.substr(0,i),gjd_mul(b,(string)""+(char)(j+'0')))!=-1)
				{
					tmp=gjd_sub1(tmp.substr(0,i),gjd_mul(b,(string)""+(char)(j+'0')))+tmp.substr(i,tmp.length());
					ans.push_back('0'+j);//模拟竖式,试商,可用二分法提高效率 
					break;
				}
			}
		}
	}
	if(ans[0]=='0' and ans.length()-1) ans.erase(0,1);
	return ans;
}

inline string gjd_mod(string a,string b)
{
	return gjd_sub(a,gjd_mul(b,gjd_div(a,b)));//求余 
}

int main()
{
	string a,b;
	cin>>a>>b;
	string div=gjd_div(a,b);
	cout<<gjd_add(a,b)<<endl<<gjd_sub(a,b)<<endl<<gjd_mul(a,b)<<endl<<div<<endl<<gjd_sub(a,gjd_mul(b,div))<<endl;
	
}
2023/7/22 01:10
加载中...