数据结构与算法|高精度

1.高精度加法

先输入两个高精度数字的字符串,再分别储存到数组当中,并且要反过来,因为数字的长度不好确定,所以我们要从个位开始相加,此时要对应数组的第一个位置,相加所得结果最大不超过s1,s2当中最长的那个数,相加时还应注意满十进一,故c[i+1] = c[i] / 10,而c[i] %= 10。最后要倒序输出,前提是首位不能为0,同时还要保留一个位,故while(c[lc]==0 && lc>1) lc--;

#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int a[101];
int b[101], c[101];
void strtoint(string src, int des[]){
	for(int i=0; i<src.size(); i++)
	{
		des[src.size()-i] = src[i] - '0';
	}
}
int main()
{
	cin >> s1 >> s2;
	//个位对齐-反转,字符转整形 
	strtoint(s1, a);
	strtoint(s2, b);
	int la = s1.size(), lb = s2.size();
	//计算c数组长度 按最长数位算 
	int lc = max(la, lb)+1; 
	//对位相加得出c数组
	 for(int i=1; i<=lc; i++)
	 {
	 	c[i] = a[i] + b[i] + c[i];
	 	c[i+1] = c[i] / 10;//进位 
	 	c[i] %= 10;        
	 }
	 //去除前导0
	 while(c[lc] == 0 && lc > 1) lc--; 
	 //倒叙打印
	 for(int i=lc; i>=1; i--)
	 {
	 	cout << c[i];
	  } 
	return 0;
}

2.高精度乘法

乘法过程:

    a4a3a2a1

X          b2b1

——————

          a4b1  a3b1  a2b1  a1b1

a4b1  a3b1  a2b2  a1b2

可见相乘后再相加时,对应的位置是i+j-1,所以c[i+j-1]都要+=,进位上来的数也要+=

#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int a[101];
int b[101], c[101];
void strtoint(string src, int des[]){
	for(int i=0; i<src.size(); i++)
	{
		des[src.size()-i] = src[i] - '0';
	}
}
int main()
{
	cin >> s1 >> s2;
	int la=s1.size(), lb=s2.size();
	strtoint(s1, a);
	strtoint(s2, b);
	int lc = la+lb;
	for(int i=1; i<=la; i++)
	{
		for(int j=1; j<=lb; j++)
		{
			c[i+j-1] += a[i] * b[j];
			c[i+j] += c[i+j-1]/10;
			c[i+j-1]%=10;
		}
	}
	while(c[lc] == 0 && lc>1) lc--;
	for(int i=lc; i>= 1; i--)cout << c[i];
	return 0;
}

 3.高精度减法

#include <bits/stdc++.h>
using namespace std;
string s1,s2;
int a[101], b[101], c[101];
void strtoint(string s, int des[]){
	for(int i=0; i<s.size(); i++)
	{
		des[s.size()-i] = s[i] - '0';
	}
}
bool cmpstr(string str1, string str2){
	if(str1.size() != str2.size())
	return str1.size() >= str2.size();
	else
	return str1 >= str2;
}
int main()
{
	cin >> s1 >> s2;
	if(cmpstr(s1,s2) == false)
	{
		cout << "-";
		swap(s1, s2);
	}
	int la = s1.size(), lb = s2.size();
	strtoint(s1,a);
	strtoint(s2,b);
	int lc = max(la, lb);
	for(int i=1; i<=lc; i++)
	{
		if(a[i] < b[i])
		{
			//借位
			a[i+1]--;//向高一位借位 
			 a[i] += 10;
		}
	    c[i] = a[i] - b[i];
	}
	while(c[lc] == 0 && lc>1) lc--;
	for(int i=lc; i >= 1; i--)cout << c[i];
	return 0;
}

4.高精度除法(高精度/低精度)

#include <bits/stdc++.h>
using namespace std;
string s;
int a[101]/*高精度*/, c[101]/*结果*/;
long long b;
int tmp;//余数 
void strtoint(string s, int a[]){
	for(int i=0; i<s.size(); i++)
	{
		a[i+1] = s[i] - '0';
	}
}
int main()
{
	cin >> s >> b;
	int la=s.size();
	strtoint(s, a);
	for(int i=1; i<=la; i++)
	{
	    c[i] = (tmp*10+a[i]) / b;
	    tmp = (tmp*10+a[i])%b;
	}
	int lc=1;
	while(c[lc] == 0 && lc<la) lc--;
	for(int i=lc; i <= la; i++)cout << c[i];
	cout << "余数" << tmp;
	return 0;}

5.

#include <bits/stdc++.h>
#define up(l,r,i) for(int i=l;i<=r;i++)
#define dn(l,r,i) for(int i=r; i>=l;i--)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
int n, lena, lenb, lenc;
int ans = 0;
int an[10005];
char b[10005];
char a[10005], c[10005];
long long best;
void cheng(){
	up(1,lena,i)
	{
		up(1,lenb,j)
		{
			c[i+j-1] += a[i] * b[j];
			c[i+j] += c[i+j-1] / 10;
			c[i+j-1] %= 10;
		}
	}
	if(c[lena+lenb]!=0) lenc = lena+lenb;
	else lenc = lena+lenb - 1;
	up(1,lenc,i){
		a[i] = c[i];
		c[i] = 0;
	}
	lena = lenc;
}
void divide(){
	int i=2;
	while(n>0){
		if(n<=i) an[i-1] = n;
		else an[i-1] = i;
		n = n-i;
		i++;
	}
	i -= 2;
	if(an[i] <= an[i-1]){
		int w = i;
		while(an[i]!=0){
			w--;
			if(w==0) w = i-1;
			an[w] ++;
			an[i] --;
		}
		i--;
	}
	 ans=i;
    a[1]=an[1];
    lena=1;
    for(int j=2;j<=i;j++){
        int k=an[j];
        int l=0;
        while(k!=0){
            l++;
            b[l]=k%10;
            k=k/10;
        }
        lenb=l;
        cheng();    
    }
}
int main(){
	IOS;
    cin >> n;
    if(n==1){
        printf("1\n");
        printf("1");
        return 0;
    }
    else if(n==2){
        printf("2\n");
        printf("2");
        return 0;
    }
    else if(n==3){
        printf("3\n");
        printf("3");
        return 0;
    }
    else if(n==4){
        printf("4\n");
        printf("4");
        return 0;
    }
    divide();
    up(1,ans,i)
        printf("%d ",an[i]);
    printf("\n");
    for(int i=lena;i>=1;i--)
        printf("%d",a[i]);
    return 0;
}

5.洛谷p1563

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 100001;
int a[MAXN], n, m, x, y, t = 1;
string name[MAXN];

int main () {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i] >> name[i];
	for (int i = 1; i <= m; i++) {
		cin >> x >> y;
		if (a[t] == x) t -= y;
		else t += y;
		if (t <= 0) t += n;       //不要用for循环,会tle
		else if (t > n) t -= n;
	}
	cout << name[t] << endl;
	return 0;
}

6.洛谷P1591阶乘之和(高精度

#include <iostream>
#include <string>
using namespace std;
int num;    		//输入的数
string ans;         //输出的数
//高精度加法
string ADD(string a, string b)
{
	string result;  //结果
	//将较大的数赋值给a,较小的数赋值给b
	if(b.length() > a.length())
	{
		string temp = a;
		a = b;
		b = temp;
	}
	int a_len = a.length();
	int b_len = b.length();
	//b补足零,方便计算
	for(int i = 0; i < a_len - b_len; i++)
	{
		b = '0' + b;
	}
	int num;        //本位
	int up = 0;     //进位
    //模拟加法
	for(int i = a_len - 1; i >= 0; i--)
	{
		int num = (a[i] - '0') + (b[i] - '0') + up;
		up = num / 10;
		num %= 10;
		result = (char)(num + '0') + result;
	}
    //若仍有进位,加上进位
	if(up)
	{
		result = (char)(up + '0') + result;
	}
	return result;
}
//高精度乘法
string MUL(string a, string b)
{
	string result;	//结果
	int a_len = a.length();
	int b_len = b.length();
	int num;        //本位
	int up = 0;		//进位
    //模拟乘法
	for(int i = a_len - 1; i >= 0; i--)
	{
 		string temp;
		for(int j = b_len - 1; j >= 0; j--)
        {
        	num = (a[i] - '0') * (b[j] - '0') + up;
			up = num / 10;
			num %= 10;
			temp = (char)(num + '0') + temp;
        }
        //若仍有进位,加上进位,记得清零
        if(up)
        {
        	temp = (char)(up + '0') + temp;
        	up = 0;
		}
		//乘以每位的权重10^k
		for(int k = 0; k < (a_len - 1) - i; k++)
		{
			temp += '0';
		}
        result = ADD(result, temp);
	}
	return result;
}
//高精度阶乘
string FAC(int n)
{
	string result = "1";
	for(int i = 1; i <= n; i++)
	{
    	//数字转化为字符串
		string a;
  		int temp = i;
		while(temp)
		{
			a = (char)(temp % 10 + '0') + a;
			temp /= 10;
		}
		result = MUL(result, a);
	}
	return result;
}
int main(void)
{
	cin >> num;
	for(int i = 1; i <= num; i++)
	{
		ans = ADD(ans, FAC(i));
	}
	cout << ans;
	return 0;
}

7.高精乘以低阶

#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[10000005];
int t, n, m, sum = 0;
void mul(int a[], int k)
{
	for(int i=1; i<a[0]; ++i)
	{
		a[i] *= k;
	}
	for(int i=1; i<a[0]; ++i)
	{
		if(a[i] > 9)
		{
			a[i+1] += a[i] / 10;
			a[i] %= 10;
		}
	}
	while(a[a[0]])
	{
		a[a[0]+1] += a[a[0]] / 10;
		a[a[0]] %= 10;
		a[0] ++;
	}
}
void check()
{
	for(int i=1; i<a[0]; ++i)
	{
		if(a[i] == m) sum ++;
	}
}
signed main()
{
	cin >> t;
	while(t--)
	{
		memset(a,0,sizeof(a));
		sum = 0;
		a[0] = 1, a[1] = 1;
		cin >> n >> m;
		for(int i=1; i<=n; ++i)
		mul(a,i);
		check();
		cout << sum << endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值