• 高精度模板汇总


    高精度模板汇总

    标签: 算法——高精度

    高精加高精

    很简单,直接做就行了

    string S;
    struct GJ{
    	int s[N],L;
    	void Print()
    		{
    			for(int i=L;i>1;--i)
    				printf("%d",s[i]);
    			printf("%d
    ",s[1]);
    		}
    }blank,A,B,Ans;
    GJ operator +(GJ X,GJ Y)
    {
    	GJ mid=blank;
    	mid.L=max(X.L,Y.L);
    	for(int i=1;i<=mid.L;++i)
    	{
    		mid.s[i]+=X.s[i]+Y.s[i];
    		mid.s[i+1]+=mid.s[i]/10;
    		mid.s[i]%=10;
    	}
    	if(mid.s[mid.L+1])mid.L++;
    	return mid;
    }
    int main()
    {
    	cin>>S;A.L=S.length();
    	for(int i=0;i<A.L;++i)
    		A.s[A.L-i]=S[i]-'0';
    	cin>>S;B.L=S.length();
    	for(int i=0;i<B.L;++i)
    		B.s[B.L-i]=S[i]-'0';
    	Ans=A+B;
    	Ans.Print();
    	return 0;
    }
    

    高精减高精

    注意一下判断高精的大小关系
    我偷懒就直接用string的库函数了。。。

    string S1,S2;
    struct GJ{
    	int s[N],L;
    	void Print()
    		{
    			for(int i=L;i>1;--i)
    				printf("%d",s[i]);
    			printf("%d
    ",s[1]);
    		}
    }blank,A,B,Ans;
    GJ operator -(GJ X,GJ Y)
    {
    	GJ mid=blank;
    	mid.L=max(X.L,Y.L);
    	for(int i=1;i<=mid.L;++i)
    	{
    		mid.s[i]+=X.s[i]-Y.s[i];
    		if(mid.s[i]<0)
    			mid.s[i+1]--,mid.s[i]+=10;
    	}
    	while(!mid.s[mid.L]&&mid.L>1)mid.L--;
    	return mid;
    }
    int main()
    {
    	bool flag=0;
    	cin>>S1;A.L=S1.length();
    	cin>>S2;B.L=S2.length();
    	if(A.L<B.L||(A.L==B.L&&S1<S2))
    	{
    		swap(S1,S2);
    		swap(A.L,B.L),flag=1;
    	}
    	for(int i=0;i<A.L;++i)
    		A.s[A.L-i]=S1[i]-'0';
    	for(int i=0;i<B.L;++i)
    		B.s[B.L-i]=S2[i]-'0';
    	Ans=A-B;
    	if(flag)putchar('-');
    	Ans.Print();
    	return 0;
    }
    

    高精乘高精

    小数的话先把小数点抠出来,在答案里加进去就ok
    负数的话特判一下就可以了

    char S[N];
    struct GJ{
    	int s[N],L;
    	void Print()
    		{
    			for(int i=L;i>1;--i)
    				printf("%d",s[i]);
    			printf("%d
    ",s[1]);
    		}
    }blank,A,B,Ans;
    GJ operator *(GJ X,GJ Y)
    {
    	GJ mid=blank;
    	mid.L=X.L+Y.L;
    	for(int i=1;i<=X.L;++i)
    		for(int j=1;j<=Y.L;++j)
    		{
    			mid.s[i+j-1]+=X.s[i]*Y.s[j];
    			mid.s[i+j]+=mid.s[i+j-1]/10;
    			mid.s[i+j-1]%=10;
    		}
    	while(!mid.s[mid.L]&&mid.L>1)mid.L--;
    	return mid;
    }
    int main()
    {
    	cin>>S;A.L=strlen(S);
    	for(int i=0;i<A.L;++i)
    		A.s[A.L-i]=S[i]-'0';
    	cin>>S;B.L=strlen(S);
    	for(int i=0;i<B.L;++i)
    		B.s[B.L-i]=S[i]-'0';
    	Ans=A*B;
    	Ans.Print();
    	return 0;
    }
    

    高精除低精

    被除数(a[) (]),除数(B),答案(ans[) (])。。。

    lst now=0;
    for(int i=1;i<=len;++i)
    {
        now=now*10+a[i];
        ans[++cnt]=now/B;
        now=now%B;
    }bool flag=0;
    for(int i=1;i<=cnt;++i)
    {
        if(ans[i])flag=1;
        if(flag)printf("%d",ans[i]);
    }puts("");
    

    高精除高精

    不停地做高精减就可以了。。。
    这个代码是(Quai)的,别介意。。。

    int compare(int aa[],int bb[])
    {
        if(aa[0]>bb[0])return 1;
        if(aa[0]<bb[0])return -1;
        for(int i=aa[0];i>0;i--)
        {
            if(aa[i]>bb[i])return 1;
            if(aa[i]<bb[i])return -1;
        }
        return 0;
    }
    void numcpy(int aa[],int bb[],int l)
    {
        for(int i=1;i<=aa[0];i++)bb[i+l-1]=aa[i];
        bb[0]=aa[0]+l-1;
    }
    int main()
    {
        cin>>a1>>b1;a[0]=a1.size();
        b[0]=b1.size(),c[0]=a[0]-b[0]+1;
        for(int i=1;i<=a[0];i++)a[i]=a1[a[0]-i]-'0';
        for(int i=1;i<=b[0];i++)b[i]=b1[b[0]-i]-'0';
        for(int i=c[0];i>0;i--)
        {
            memset(t,0,sizeof(t));
            numcpy(b,t,i);
            while(compare(a,t)>=0)
            {
                c[i]++;
                if(!compare(a,t)){a[0]=0;continue;}
                for(int i=1;i<=a[0];i++)
                {
                    if(a[i]<t[i])
                        a[i+1]--,a[i]+=10;
                    a[i]-=t[i];
                }
                while(a[0]>0&&!a[a[0]])a[0]--;
            }
        }
        while(c[0]>0&&!c[c[0]])c[0]--;
        if(!c[0])puts("0");
        else for(int i=c[0];i>0;i--)cout<<c[i];
        return 0;
    }
    

    高精取模低精

    你把读入优化的板子改一下,一边读一边(Orz)就行了。。。

    lst Read()
    {
        char ch=getchar();lst s=0;
        while (!(ch>='0'&&ch<='9'))ch=getchar();
        while ((ch>='0'&&ch<='9'))s=(s*10+ch-'0')%mod,ch=getchar();
        return s?s:mod;
    }
    int main()
    {
        scanf("%lld",&mod);
        printf("%lld
    ",Read());
    }
    

    尾言

    其实这些都可以放进一个程序operator
    我就懒得再弄了
    高精还是很简单的,就是写得烦
    如今很多题目都采用取模的方法避免高精,所以掌握就行了
    我也就是Noip前练习一下而已。。。

  • 相关阅读:
    几个常用的排序算法
    计算机网络的一丢丢知识点
    最小的k个数
    操作系统的一丢丢知识点
    MySQL一丢丢知识点的了解
    B+树
    重建二叉树
    Redis简介
    shell脚本常用案例-5.10
    笔记-网络学习-子网划分
  • 原文地址:https://www.cnblogs.com/cjoierljl/p/9669337.html
Copyright © 2020-2023  润新知