[백준 2338] 긴자리 계산 (C#, C++) - soo:bak
작성일 :
문제 링크
설명
두 정수 A와 B가 주어집니다. 각 정수는 최대 1000자리의 양의 정수 또는 음의 정수입니다.
A + B, A - B, A × B의 세 가지 연산 결과를 각각 한 줄씩 출력하는 간단한 문제입니다.
하지만, 일반적인 정수 타입으로는 1000자리의 수를 표현할 수 없으므로, 임의 정밀도 산술 또는 문자열 기반 큰 수 연산이 필요합니다.
접근법
C#의 경우 System.Numerics.BigInteger 타입이 임의 크기의 정수를 지원하므로, 입력을 BigInteger로 파싱한 후 기본 산술 연산자를 사용하면 됩니다.
C++의 경우 표준 라이브러리에 큰 수 타입이 없으므로 문자열 기반으로 직접 구현합니다.
입력을 문자열로 받아 부호와 절댓값을 분리한 후, 각 연산을 절댓값에 대해 수행하고 마지막에 부호를 결정합니다.
덧셈은 두 수의 부호가 같으면 절댓값을 더하고, 다르면 절댓값 크기를 비교하여 큰 쪽에서 작은 쪽을 뺍니다.
뺄셈은 부호를 반전시킨 후 덧셈으로 처리하며,
곱셈은 절댓값끼리 곱한 후 부호 규칙을 적용합니다.
절댓값 덧셈은 낮은 자릿수부터 각 자리를 더하고 올림을 다음 자리로 전달합니다.
절댓값 뺄셈은 큰 수에서 작은 수를 빼되, 현재 자리 값이 부족하면 받아내림을 처리합니다.
절댓값 곱셈은 두 수의 각 자릿수를 곱하여 결과 배열의 적절한 위치에 누적합니다.
모든 연산 후 앞자리 0을 제거하고, 결과가 0이면 부호를 붙이지 않습니다.
Code
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
using System.Numerics;
namespace Solution {
class Program {
static void Main(string[] args) {
var a = BigInteger.Parse(Console.ReadLine()!);
var b = BigInteger.Parse(Console.ReadLine()!);
Console.WriteLine(a + b);
Console.WriteLine(a - b);
Console.WriteLine(a * b);
}
}
}
C++
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
#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
string trimZeros(const string& s) {
size_t pos = s.find_first_not_of('0');
return (pos == string::npos) ? "0" : s.substr(pos);
}
int compareAbs(const string& a, const string& b) {
string x = trimZeros(a), y = trimZeros(b);
if (x.size() != y.size()) return x.size() < y.size() ? -1 : 1;
if (x == y) return 0;
return x < y ? -1 : 1;
}
string addAbs(const string& a, const string& b) {
string result;
int carry = 0, i = (int)a.size() - 1, j = (int)b.size() - 1;
while (i >= 0 || j >= 0 || carry) {
int sum = carry;
if (i >= 0) sum += a[i--] - '0';
if (j >= 0) sum += b[j--] - '0';
result.push_back(char('0' + (sum % 10)));
carry = sum / 10;
}
reverse(result.begin(), result.end());
return trimZeros(result);
}
string subAbs(const string& a, const string& b) {
string result;
int borrow = 0, i = (int)a.size() - 1, j = (int)b.size() - 1;
while (i >= 0) {
int diff = (a[i] - '0') - borrow;
if (j >= 0) diff -= (b[j] - '0');
if (diff < 0)
diff += 10, borrow = 1;
else
borrow = 0;
result.push_back(char('0' + diff));
--i; --j;
}
while (result.size() > 1 && result.back() == '0') result.pop_back();
reverse(result.begin(), result.end());
return trimZeros(result);
}
string mulAbs(const string& a, const string& b) {
vi prod(a.size() + b.size(), 0);
for (int i = (int)a.size() - 1; i >= 0; --i) {
for (int j = (int)b.size() - 1; j >= 0; --j) {
int idx = i + j + 1;
int val = (a[i] - '0') * (b[j] - '0') + prod[idx];
prod[idx] = val % 10;
prod[idx - 1] += val / 10;
}
}
string result;
for (int digit : prod) result.push_back(char('0' + digit));
return trimZeros(result);
}
string addSigned(const string& a, const string& b) {
int signA = (a[0] == '-') ? -1 : 1;
int signB = (b[0] == '-') ? -1 : 1;
string absA = (signA == -1) ? a.substr(1) : a;
string absB = (signB == -1) ? b.substr(1) : b;
absA = trimZeros(absA), absB = trimZeros(absB);
if (absA == "0") signA = 1;
if (absB == "0") signB = 1;
if (signA == signB) {
string sum = addAbs(absA, absB);
if (sum == "0") return "0";
return (signA == -1 ? "-" : "") + sum;
}
int cmp = compareAbs(absA, absB);
if (cmp == 0) return "0";
bool aIsGreater = (cmp > 0);
string diff = aIsGreater ? subAbs(absA, absB) : subAbs(absB, absA);
int sign = aIsGreater ? signA : signB;
if (diff == "0") return "0";
return (sign == -1 ? "-" : "") + diff;
}
string subSigned(const string& a, const string& b) {
string negB = (b[0] == '-') ? b.substr(1) : "-" + b;
return addSigned(a, negB);
}
string mulSigned(const string& a, const string& b) {
int signA = (a[0] == '-') ? -1 : 1;
int signB = (b[0] == '-') ? -1 : 1;
string absA = (signA == -1) ? a.substr(1) : a;
string absB = (signB == -1) ? b.substr(1) : b;
absA = trimZeros(absA), absB = trimZeros(absB);
string product = mulAbs(absA, absB);
if (product == "0") return "0";
int sign = signA * signB;
return (sign == -1 ? "-" : "") + product;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string A, B; cin >> A >> B;
cout << addSigned(A, B) << "\n";
cout << subSigned(A, B) << "\n";
cout << mulSigned(A, B) << "\n";
return 0;
}