计算机考研复试--牛客网--C语言练习--Day5

  1. 1 背景
  2. 2 题目:Powerful Calculator
    1. 题目描述
    2. 输入描述:
    3. 输出描述:
    4. 示例
      1. 输入
      2. 输出
    5. 代码
  3. 3 分析

1 背景

第5天的题目实在搞不定了,于是就参考了一下排名第一的大佬的代码

2 题目:Powerful Calculator

题目描述

Today, facing the rapid development of business, SJTU recognizes that more powerful calculator should be studied, developed and appeared in future market shortly. SJTU now invites you attending such amazing research and development work. In most business applications, the top three useful calculation operators are Addition (+), Subtraction (-) and Multiplication (×) between two given integers. Normally, you may think it is just a piece of cake. However, since some integers for calculation in business application may be very big, such as the GDP of the whole world, the calculator becomes harder to develop. For example, if we have two integers 20 000 000 000 000 000 and 4 000 000 000 000 000, the exact results of addition, subtraction and multiplication are: 20000000000000000 + 4000000000000000 = 24 000 000 000 000 000 20000000000000000 - 4000000000000000 = 16 000 000 000 000 000 20000000000000000 × 4000000000000000 = 80 000 000 000 000 000 000 000 000 000 000 Note: SJTU prefers the exact format of the results rather than the float format or scientific remark format. For instance, we need “24000000000000000” rather than 2.4×10^16. As a programmer in SJTU, your current task is to develop a program to obtain the exact results of the addition (a + b), subtraction (a - b) and multiplication (a × b) between two given integers a and b.

意思大致是:
今天,面对业务的快速发展,上海交通大学认识到,更强大的计算器应该研究,开发和出现在未来的市场很快。上海交通大学诚邀您参加如此精彩的研发工作。在大多数业务应用程序中,前三个有用的计算运算符是两个给定整数之间的加法(+)、减法(-)和乘法(×)。通常,你可能会认为这只是小菜一碟。然而,由于商业应用中计算的一些整数可能非常大,比如全球的GDP,使得计算器的开发变得更加困难。例如,如果我们有两个整数20 000 000 000和4 000 000 000 000 000,那么加、减、乘的精确结果是:200000000000+40000000000=24 000 000 000 000 000 000 000-40000000000=16 000 000 000 000 000 000 000×40000000000=8 000 000 000 000 000 000 000 000注:上海交通大学倾向于结果的精确格式,而不是浮点数格式或科学备注格式。例如,我们需要“24000000000000000”,而不是2.4×10^16。作为上海交通大学的程序员,您当前的任务是开发一个程序,以获得两个给定整数a和b之间的加法(a+b)、减法(a-b)和乘法(a×b)的精确结果。

输入描述:

Each case consists of two separate lines where the first line gives the integer a and the second gives b (|a| <10^400 and |b| < 10^400).

意思大致是:
每种情况由两行组成,第一行给出整数a,第二行给出b(| a |<10^400和| b |<10^400)。

输出描述:

For each case, output three separate lines showing the exact results of addition (a + b), subtraction (a - b) and multiplication (a × b) of that case, one result per lines.

意思大致是:
对于每种情况,输出三行,分别显示该情况的加法(a+b)、减法(a-b)和乘法(a×b)的精确结果,每行一个结果。

示例

输入

20000000000000000
4000000000000000

输出

24000000000000000
16000000000000000
80000000000000000000000000000000

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char stra[500];
char strb[500];
struct bign {
int d[1000];
int len;
};
struct bign data1;
struct bign data2;
void init(struct bign* a) {
memset((*a).d, 0, sizeof((*a).d));
(*a).len=0;
}
struct bign add(struct bign a, struct bign b) {
int i;
struct bign c;
init(&c);
int carry = 0;
for(i = 0; i < a.len || i < b.len; i++) {
int temp = a.d[i] + b.d[i] + carry;
c.d[c.len++] = temp % 10;
carry = temp / 10;
}
if(carry != 0) {
c.d[c.len++] = carry;
}
return c;
}
struct bign minu(struct bign a, struct bign b) {
int i;
struct bign c;
init(&c);
for(i = 0; i < a.len || i < b.len; i++) {
if(a.d[i] < b.d[i]) {
a.d[i+1]--;
a.d[i] += 10;
}
c.d[c.len++] = a.d[i] - b.d[i];
}
while(c.len - 1 >= 1 && c.d[c.len-1] == 0) {
c.len--;
}
return c;
}
struct bign multi(struct bign a, struct bign b) {
struct bign c;
int i, j;
init(&c);
int carry = 0;
for(i = 0; i < a.len; i++) {
for(j = 0; j < b.len; j++) {
int temp = c.d[i+j];
c.d[i+j] = (c.d[i+j] + carry + a.d[i] * b.d[j]) % 10;
carry = (a.d[i] * b.d[j] + carry + temp) / 10;
}
int m = i + j;
while(carry != 0) {
c.d[m++] = carry % 10;
carry /= 10;
}
}
c.len = a.len + b.len + 1;
while(c.len - 1 >= 1 && c.d[c.len-1] == 0) {
c.len--;
}
return c;
}
int compare(struct bign a, struct bign b) {
if(a.len > b.len)
return 1;
else if(a.len < b.len)
return - 1;
else {
int i;
for(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;
}
}
void print(struct bign a) {
int i;
for(i = a.len - 1; i >= 0; i--) {
printf("%d", a.d[i]);
}
printf("\n");
}
void f_add(struct bign a, struct bign b, int signa, int signb, int res) {
struct bign c;
if(signa == 1 && signb == 1) {
c=add(a, b);
print(c);
}
else if(signa == -1 && signb == -1) {
c=add(a, b);
printf("-");
print(c);
}
else if(signa == 1 && signb == -1) {
if(res == -1) {
c=minu(b, a);
printf("-");
}
else
{
c=minu(a, b);
}
print(c);
}
else{
if(res == 1) {
c = minu(a, b);
printf("-");
}
else {
c=minu(b, a);
}
print(c);
}
}
void f_minu(struct bign a, struct bign b, int signa, int signb, int res) {
struct bign c;
if(signa == 1 && signb == -1) {
c = add(a, b);
print(c);
}
else if(signa == -1 && signb == 1) {
c=add(a, b);
printf("-");
print(c);
}
else if(signa == 1 && signb == 1) {
if(res == -1) {
c=minu(b, a);
printf("-");
}
else {
c = minu(a, b);
}
print(c);
}
else {
if(res == 1) {
c = minu(a, b);
printf("-");
}
else {
c=minu(b, a);
}
print(c);
}
}
void f_multi(struct bign a, struct bign b, int signa, int signb,int res) {
struct bign c;
if(signa * signb >= 0) {
c = multi(a, b);
print(c);
}
else {
c = multi(a, b);
printf("-");
print(c);
}
}
int main() {
int i, j, k;
while(scanf("%s %s", stra, strb) != EOF) { //输入a,b两个数字字符
int lena, lenb;
int len1, len2;
int signa = 1; //默认输入a为正数
int signb = 1; //默认输入b为正数
if(stra[0] == '-') //如果该数字是负数
signa = -1;
if(strb[0] == '-') //如果该数字是负数
signb = -1;
lena = strlen(stra); //求a数字字符的长度
len1 = lena;
if(signa == -1) //如果是负数,字符长度减1
len1 = lena - 1;
lenb = strlen(strb); //求b数字字符的长度
len2 = lenb;
if(signb == -1) //如果是负数,字符长度减1
len2 = lenb - 1;
data1.len = len1;
for(i = 0; i < len1; i++) {
//每个数字的ASCII减去'0'的ASCII得到该数字的大小
data1.d[i] = stra[lena-i-1] - '0';
}
data2.len = len2;
for(i = 0; i < len2; i++) {
//每个数字的ASCII减去'0'的ASCII得到该数字的大小
data2.d[i] = strb[lenb-i-1] - '0';
}
int res = compare(data1, data2);
f_add(data1, data2, signa, signb, res); //加法
f_minu(data1, data2, signa, signb, res); //减法
f_multi(data1, data2, signa, signb, res); //乘法
}
return 0;
}

3 分析

  • 今天题目真心不好做,我现在怀疑出这个题的人的脑回路了

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 xingshuaikun@163.com。

×

喜欢就点赞,疼爱就打赏