大数存储问题 题目:读入n,m,输出 n!*m!. (1<=n,m<=100) 结果的位数不超过400. 提示:定义一个数组a[400],定义乘法运算,每次乘法结果用数组保存 输入: 输入仅一行,有两个数n,m.输入格式:scanf("%d %d",&n,&m); 输出: 输出仅一行,为题目所要求的答案.最后换行. 输出格式:printf("%d",a[i]); ................. printf("\n"); 样例输入: 100 90 样例输出: 138656248189732152054159609718432247180282092567575172939636909 224427929240834642263988043338170905744175653189424779336521852 536242160190545537133916649622615351174407746524657461692702500 613722228638559932561661493048332720605069264786823205531680768 000000000000000000000000000000000000000000000
时间: 2023-05-03 08:02:30 浏览: 355
这道题目要求计算n!和m!的积,最后输出结果且结果的位数不超过400位。
解题思路:由于直接计算n!和m!的乘积可能会导致溢出,所以我们需要对n!和m!进行分解,然后再进行乘积操作。具体而言,我们可以将n!和m!分别保存在两个数组中,并且每一位都单独存储,最后再进行乘积计算。由于每一位的值都是0~9之间的整数,所以我们可以用数组来存储。在计算的过程中,需要注意进位和数组下标的问题。
代码如下:
相关问题
c语言编写题目:读入n,m,输出 n!∗m!.(1<=n,m<=100) 结果的位数不超过400. 提示:定义一个数组a[400],定义乘法运算,每次乘法结果用数组保存输入: 输入仅一行,有两个数n,m.输入格式:scanf("%d %d",&n,&m); 输出: 输出仅一行,为题目所要求的答案.最后换行. 输出格式:printf("%d",a[i]); printf("\n");
以下是 C 语言编写的程序代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_DIGITS 400
void multiply(int a[], int b) {
int carry = 0;
for (int i = 0; i < MAX_DIGITS; i++) {
int product = a[i] * b + carry;
a[i] = product % 10;
carry = product / 10;
}
}
void print_result(int a[]) {
int i;
for (i = MAX_DIGITS - 1; i >= 0; i--) {
if (a[i] != 0) break;
}
if (i == -1) {
printf("0\n");
} else {
for (; i >= 0; i--) {
printf("%d", a[i]);
}
printf("\n");
}
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
int a[MAX_DIGITS];
memset(a, 0, sizeof(a));
a[0] = 1;
for (int i = 2; i <= n; i++) {
multiply(a, i);
}
for (int i = 2; i <= m; i++) {
multiply(a, i);
}
print_result(a);
return 0;
}
```
程序逻辑:
- 定义一个大小为 400 的数组 `a`,用于存储大数乘法的结果;
- 读入 `n` 和 `m`;
- 将数组 `a` 的所有元素初始化为 0,将 `a[0]` 初始化为 1;
- 循环计算 `n!`,将结果存储在数组 `a` 中;
- 循环计算 `m!`,将结果存储在数组 `a` 中;
- 输出乘积的结果,即 `n! * m!`。
其中,大数乘法的实现方式为竖式乘法,具体过程为:对于数组 `a` 中的每一个元素,都将其与乘数 `b` 相乘,并将进位传递到下一个元素中。注意,由于 `n` 和 `m` 都不超过 100,因此数组 `a` 最多只需要存储 200 位数字。
C语言实现:1.8 无符号大数加、减运算。程序设计中经常遇到无符号大数加、减运算问题,请在样例程序Ex1.4基础上实现无符号大数减运算。题目要求输入两个无符号大数,保证一个大数不小于第二个大数,输出它们的和、差。 输入格式: 两个无符号大数,前一个大于等于第二个。 输出格式: 第1行为两个无符号大数相加结果,后一行为两个无符号大数相减结果。
以下是 C 语言的实现代码:
```c
#include <stdio.h>
#include <string.h>
#define MAXN 1000
struct bign
{
int d[MAXN], len;
bign() // 结构体初始化
{
memset(d, 0, sizeof(d));
len = 0;
}
};
bign change(char str[]) // 将字符串转换为 bign 结构体
{
bign a;
a.len = strlen(str);
for (int i = 0; i < a.len; i++)
a.d[i] = str[a.len - 1 - i] - '0';
return a;
}
int compare(bign a, bign b) // 比较两个大数的大小,a > b 返回 1,a = b 返回 0,a < b 返回 -1
{
if (a.len > b.len)
return 1;
else if (a.len < b.len)
return -1;
else
{
for (int i = a.len - 1; i >= 0; i--)
{
if (a.d[i] > b.d[i])
return 1;
else if (a.d[i] < b.d[i])
return -1;
}
return 0;
}
}
bign add(bign a, bign b) // 无符号大数加法
{
bign c;
int carry = 0; // 进位初始化为 0
for (int i = 0; i < a.len || i < b.len; i++)
{
int tmp = a.d[i] + b.d[i] + carry; // 当前位的值等于两个数当前位的和加上上一位的进位
c.d[c.len++] = tmp % 10; // 当前位的值等于 tmp 模 10 的余数
carry = tmp / 10; // 计算进位
}
if (carry != 0) // 如果最高位有进位,将进位加到最高位上
c.d[c.len++] = carry;
return c;
}
bign sub(bign a, bign b) // 无符号大数减法
{
bign c;
for (int i = 0; i < a.len || i < b.len; i++)
{
if (a.d[i] < b.d[i]) // 如果 a 的当前位小于 b 的当前位,借位
{
a.d[i] += 10; // 当前位加上 10
a.d[i + 1]--; // 下一位减 1
}
c.d[c.len++] = a.d[i] - b.d[i]; // 计算当前位的差
}
while (c.len > 1 && c.d[c.len - 1] == 0) // 去除高位的 0
c.len--;
return c;
}
void print(bign a) // 输出 bign 结构体
{
for (int i = a.len - 1; i >= 0; i--)
printf("%d", a.d[i]);
printf("\n");
}
int main()
{
char str1[MAXN], str2[MAXN];
scanf("%s%s", str1, str2);
bign a = change(str1), b = change(str2);
bign c = add(a, b), d = sub(a, b);
print(c);
print(d);
return 0;
}
```
思路如下:
首先,我们定义一个结构体 `struct bign`,用来表示无符号大数。结构体中包含一个整型数组 `int d[MAXN]` 和一个整型变量 `int len`,分别用来存储数字的每一位和数字的长度。
接着,我们实现三个函数:
- `change(char str[])`:将一个字符串转换成一个 `bign` 结构体。
- `compare(bign a, bign b)`:比较两个无符号大数的大小,返回 1 表示第一个数大于第二个数,返回 0 表示两个数相等,返回 -1 表示第一个数小于第二个数。
- `add(bign a, bign b)`:实现两个无符号大数的加法。
在实现减法之前,我们需要先解决一个问题:如何计算一个无符号大数 `a` 减去另一个无符号大数 `b` 的差。我们可以先将 `b` 按照加法的方式取反(即将每一位上的数字 9 减去它原来的数字),然后将取反后的 `b` 和 `a` 相加,即可得到 `a-b` 的值。
具体实现方法如下:
- 先将 `a` 和 `b` 的长度都扩展到相等的长度(不足的高位用 0 补齐)。
- 从低位到高位,用 `a` 的当前位减去 `b` 的当前位,如果 `a` 的当前位小于 `b` 的当前位,将当前位向高位借位。
- 如果减完后最高位为 0,则将高位的 0 去掉。
最后,我们编写主函数,读入两个字符串,将它们转换成 `bign` 结构体,然后分别调用加法和减法函数,输出它们的和和差。
阅读全文