问题描述
求两个大的正整数相除的商
输入数据
第 1 行是测试数据的组数 n,每组测试数据占 2 行,第 1 行是被除数,第 2 行是除数。
每组测试数据之间有一个空行,每行数据不超过 100 个字符
输出要求
n 行,每组测试数据有一行输出是相应的整数商
解题思路
基本的思想是反复做减法,看看从被除数里最多能减去多少个除数,商就是多少。一个一个减显然太慢,如何减得更快一些呢?以 7546 除以 23 为例来看一下:开始商为 0。先减去 23 的 100 倍,就是 2300,发现够减 3 次,余下 646。于是商的值就增加 300。然后用 646减去 230,发现够减 2 次,余下 186,于是商的值增加 20。最后用 186 减去 23,够减 8 次,因此最终商就是 328。所以本题的核心是要写一个大整数的减法函数,然后反复调用该函数进行减法操作
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 200
int x[MAX_LEN + 20], y[MAX_LEN + 20], z[MAX_LEN + 20];
char a[MAX_LEN + 20], b[MAX_LEN + 20];
void debug_print(const int x[], int len)
{
int i;
for (i = 0; i < len; i++)
printf("%d", x[i]);
printf("\n");
}
void char_to_int(const char s[ ], int x[ ])
{
int i = 0;
int len = strlen(s);
memset(x, 0, MAX_LEN + 20);
int j = 0;
for (i = len - 1; i >= 0; i--)
{
x[j++] = s[i] - ‘0‘;
}
}
int cal_length( const int x[])
{
int i = 0;
int count = 0;
for (i = MAX_LEN - 1; i >= 0; i--)
{
if (x[i])
{
count = i + 1;
break;
}
}
return count;
}
int big_int_sub( int x[], const int y[])
{
int i = 0;
const int lenx = cal_length(x);
const int leny = cal_length(y);
//判断x 是否大于 y
if (lenx < leny)
return -1;
else if (lenx == leny)
{
for (i = lenx - 1; i >= 0; i--)
{
if (x[i] < y[i])
return -1;
else if (x[i] == y[i])
continue;
else
break;
}
}
//逐位想减
for (i = 0; i < MAX_LEN; i++)
{
x[i] = x[i] - y[i];
if (x[i] < 0)
{
x[i] = x[i] + 10;
x[i + 1] --;
}
}
return 1;
}
void big_int_div(int x[], const int y[], int z[])
{
int i , j = 0;
int *copy_y = NULL;
memset(z, 0, MAX_LEN + 20);
const int lenx = cal_length(x);
int leny = cal_length(y);
int times = lenx - leny;
copy_y = (int *)malloc(sizeof(int ) * MAX_LEN);
memcpy(copy_y, y, sizeof(int) * MAX_LEN);
// 将复制的copy_y右移times位,跟x的长度相等
for (i = lenx - 1; i >= 0; i--)
{
if (i >= times)
copy_y[i] = copy_y[i - times];
else
copy_y[i] = 0; //低位补0
}
//x开始减copy_y,减到不够减之后,再减去 copy_y右移times - 1位 直到最后不够减
leny = lenx;
for (i = 0; i <= times; i++)
{
while ( big_int_sub(x, copy_y) >= 0)
z[times - i] ++;
//copy_y 左移一位 即是y的右移times - 1位
for (j = 1; j < leny; j++)
copy_y[j - 1] = copy_y[j];
copy_y[--leny] = 0;
}
for (i = 0; i < MAX_LEN ; i++)
{
if (z[i] >= 10)
{
z[i + 1] += z[i] / 10;
z[i] = z[i] % 10;
}
}
}
void big_int_print(const int z[])
{
bool flag = 0;
int i = 0;
for (i = MAX_LEN; i >= 0; i--)
{
if (flag)
printf("%d", z[i]);
else if (z[i])
{
printf("%d", z[i]);
flag = 1;
}
}
if (!flag)
printf("0");
printf("\n");
}
int main( )
{
int n;
scanf("%d", &n);
while (n--)
{
scanf("%s", a);
scanf("%s", b);
int len = 0;
int lenx = strlen(a);
int leny = strlen(b);
len = lenx - leny;
if (len < 0)
printf("0\n");
char_to_int(a, x);
char_to_int(b, y);
big_int_div(x, y, z);
big_int_print(z);
}
return 0;
}
时间: 2024-10-02 20:11:49