洛谷【P2005】A/B Problem II

题目传送门:https://www.luogu.org/problemnew/show/P2005

高精除低精:https://www.cnblogs.com/AKMer/p/9724556.html

高精度除法板子。和高精除低精不同的是,除数不能直接去和当前位相除,而是能减一次算一次……

时间复杂度:\(O(len)\)

空间复杂度:\(O(len)\)

代码如下:

#include <cstdio>
#include <cstring>
using namespace std;

const int maxn=25005;

char s[maxn];

struct Bignum {
    int num[maxn];

    void make() {
        num[0]=strlen(s+1);
        for(int i=1;i<=num[0];i++)
            num[i]=s[num[0]-i+1]-'0';
    }

    void print() {
        for(int i=num[0];i;i--)
            printf("%d",num[i]);
    }

    bool operator>=(const Bignum &a)const {
        if(num[0]!=a.num[0])return num[0]>a.num[0];
        for(int i=num[0];i;i--)
            if(num[i]!=a.num[i])return num[i]>a.num[i];
        return 1;
    }//比较

    Bignum operator-(const Bignum &a)const {
        Bignum c;memcpy(c.num,num,sizeof(c.num));
        for(int i=1;i<=c.num[0];i++) {
            if(c.num[i]<a.num[i])c.num[i+1]--,c.num[i]+=10;
            c.num[i]-=a.num[i];
        }
        while(!c.num[c.num[0]]&&c.num[0]>1)c.num[0]--;
        return c;
    }//高精度减法
}a,b,c;



void cpy(Bignum &a,int id,Bignum fake) {
    for(int i=1;i<=fake.num[0];i++)
        a.num[id+i-1]=fake.num[i];
    a.num[0]=fake.num[0]+id-1;
}//把fake丢到a里,并且以id位开始,1到id-1都是0

Bignum operator/(Bignum a,Bignum b) {
    Bignum c;memset(c.num,0,sizeof(c.num));
    c.num[0]=a.num[0]-b.num[0]+1;
    for(int i=c.num[0];i;i--) {
        Bignum tmp;memset(tmp.num,0,sizeof(tmp.num));
        cpy(tmp,i,b);while(a>=tmp)c.num[i]++,a=a-tmp;//能减就减
    }while(c.num[0]>1&&!c.num[c.num[0]])c.num[0]--;
    return c;
}

int main() {
    scanf("%s",s+1);a.make();
    scanf("%s",s+1);b.make();
    c=a/b;c.print();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AKMer/p/9726286.html