-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
求两个大的正整数相除的商。
输入
- 第1行是被除数,第2行是除数。每个数均不超过100位。 输出
- 一行,相应的商的整数部分 样例输入
-
2376 24
样例输出
-
99
把除法转换成大整数减法,商是几就是能减多少次除数,但是一直减太慢了,会超时(比如1000000000000000000…0/10),所以每次减掉被除数的 1 0 n 10^n 10n倍,直到不能减了再缩小10倍。
如 120 / 2,先把20变为 2 ∗ 1 0 2 = 200 2 * 10^2 = 200 2∗102=200(位数和被除数一样多),发现120不够减,于是缩小10倍,变为20,发现能减6次,于是答案是60.
并且在扩大10的n次幂的时候不用做乘法,在低位补0就好了,缩小倍数的时候也是一样,去掉低位0.
AC代码如下:
#include<iostream>
#include<cstring>
using namespace std;
struct BigInt {
int bsize;
int digit[10000];
void init() {
bsize = 0;
for (int i = 0; i < 10000; ++i)digit[i] = 0;
}
void set(char str[]) {
init();
int L = strlen(str);
for (int i = L - 1, c = 1, t = 0, j = 0; i >= 0; --i) {
int x = str[i] - '0';
t += x * c;
c *= 10;
++j;
if (j == 1 || i == 0) {
digit[bsize++] = t;
t = 0;
c = 1;
j = 0;
}
}
}
void output() {
if (bsize == 0) { printf("0\n"); return; }
for (int i = bsize - 1; i >= 0; --i) {
if (i == bsize - 1) printf("%d", digit[i]);
else
{
printf("%01d", digit[i]);
}
}
printf("\n");
}
//向右移x位
void move(int x) {
if (x == 0)return;
for (int i = bsize - 1; i >= 0; --i) {
digit[i + x] = digit[i];
}
for (int i = 0; i < x; ++i) {
digit[i] = 0;
}
bsize += x;
}
//向左移x位
void moveL(int x) {
if (x == 0)return;
for (int i = 0; i <= bsize - x; ++i) {
digit[i] = digit[i + x];
}
for (int i = bsize - x + 1; i < bsize - 1; ++i) {
digit[i] = 0;
}
bsize -= x;
}
int isBigger(BigInt A) {
bool f = false;
if (bsize > A.bsize)return 1;
if (bsize < A.bsize)return -1;
for (int i = bsize - 1; i >= 0; --i) {
if (digit[i] > A.digit[i]) f = true;
else if (digit[i] < A.digit[i]) {
if (!f) return -1;
}
}
return f ? 1 : 0;
}
//默认被减数大于等于减数
BigInt operator - (const BigInt &A)const {
BigInt ret;
ret.init();
bool isBor = false;
for (int i = 0; i < bsize || i < A.bsize; ++i) {
int tmp = isBor ? digit[i] - A.digit[i] - 1 : digit[i] - A.digit[i];
if (tmp < 0) {
isBor = true;
tmp += 10;
}
else
{
isBor = false;
}
ret.digit[ret.bsize++] = tmp;
}
bool f = false;
for (int i = ret.bsize - 1; i >= 0; --i) {
if (ret.digit[i] != 0) {
f = true;
break;
}
if (ret.digit[i] == 0 && !f) {
ret.bsize--;
}
}
return ret;
}
};
int main()
{
char str1[210];
char str2[210];
while (~scanf("%s%s", str1, str2)) {
if (strcmp(str2, "0") == 0) {
printf("0\n");
continue;
}
BigInt B1, B2;
B1.set(str1);
B2.set(str2);
int ans[155];
memset(ans, 0, sizeof(ans));
BigInt ret;
ret.init();
if (B1.isBigger(B2) == -1) {
printf("0\n");
continue;
}
if (B1.isBigger(B2) == 0) {
printf("1\n");
continue;
}
ret = B1 - B2;
ans[0] ++;
int nTimes = ret.bsize - B2.bsize;
if (nTimes < 0) {
goto OutputResult;
}
else if (nTimes > 0)
{
B2.move(nTimes);
}
for (int j = 0; j <= nTimes; ++j) {
int nTmp;
while (ret.isBigger(B2) > 0)
{
ret = ret - B2;
ans[nTimes - j]++;
}
if (ret.isBigger(B2) == 0)
{
ret = ret - B2;
ans[nTimes - j]++;
break;
}
B2.moveL(1);
}
OutputResult:
for (int i = 0; i < 150; ++i) {
if (ans[i] >= 10) {
ans[i + 1] += ans[i] / 10;
ans[i] %= 10;
}
}
bool f = false;
for (int i = 150; i >= 0; --i) {
if (f)printf("%d", ans[i]);
else if (ans[i]) {
printf("%d", ans[i]);
f = true;
}
}
printf("\n");
}
system("pause");
return 0;
}
不太好的是使用了goto语句。。