洛谷【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;
}
posted @ 2018-09-29 19:10  AKMer  阅读(250)  评论(0编辑  收藏  举报