Zerojudge a021:大數運算 & d427:大數根號
a021:大數運算
加法:用兩個 $\text{vector}$ 存,若超過 $10^9$ 則進位。
減法:先比較 $\text{vector}$ 的大小,如果 $v_1<v_2$ 先輸出 $`-'$ 再交換,中間相減如果小於 $0$ 要借位,最後把多餘的 $0$ 去掉。
乘法:把 $v_1$ 第 $i$ 位和 $v_2$ 第 $j$ 位相乘,取餘數放在第 $i+j$ 位,最後處理多出的數。
除法:把被除數一位一位加上去,去比較比除數的幾倍大,輸出倍數然後扣掉,除數倍數可以先存。
#pragma GCC optimize("O3")
#include <iostream>
#include <vector>
#define vint vector<int>
using namespace std;
const int mod = 1000000000;
bool bigger (vint v1, vint v2) {
if (v1.size() > v2.size() || v1 == v2)
return 1;
if (v1.size() < v2.size())
return 0;
for (int i = v1.size() - 1; i >= 0; i--) {
if (v1[i] > v2[i])
return 1;
if (v1[i] < v2[i])
return 0;
}
}
vint ItoV (int n) {
vint re;
re.push_back (n);
return re;
}
vint StoV (string str) {
vint re;
int num = 0, now = 0, ten = 1;
for (int i = str.length() - 1; i >= 0; i--) {
num += (str[i] - '0') * ten;
now++;
if (now == 9)
now = 0, ten = 1, re.push_back (num), num = 0;
else
ten *= 10;
}
if (num)
re.push_back (num);
return re;
}
void out (vint vec) {
cout << vec[vec.size() - 1];
for (int i = vec.size() - 2; i >= 0; i--) {
int len = 0, num = vec[i];
do {
len++;
num /= 10;
} while (num);
len = 9 - len;
while (len--)
cout << '0';
cout << vec[i];
}
cout << '\n';
}
vint add (vint v1, vint v2, bool is) {
vint re;
long long num = 0;
for (int i = 0;; i++) {
if (i >= v1.size() && i >= v2.size() && num == 0)
break;
if (i < v1.size())
num += v1[i];
if (i < v2.size())
num += v2[i];
re.push_back (num % mod);
num /= mod;
}
if (is == 1)
out (re);
else
return re;
}
vint sub (vint v1, vint v2, bool is) {
if (is == 1 && bigger (v1, v2) == 0) {
cout << '-';
vint temp = v2;
v2 = v1, v1 = temp;
}
vint re;
long long num = 0;
for (int i = 0; i < v1.size(); i++) {
num = v1[i] - num;
if (i < v2.size())
num -= v2[i];
if (num >= 0)
re.push_back (num), num = 0;
else
re.push_back (mod + num), num = 1;
}
int sum = 0;
for (int i = re.size() - 1; i >= 0; i--) {
if (re[i] == 0)
sum++;
else
break;
}
re.resize (re.size() - sum);
if (re.size() == 0)
re.push_back (0);
if (is == 1)
out (re);
else
return re;
}
vint mult (vint v1, vint v2, bool is) {
if ( ( (v1.size() == 1 && v1[0] == 0) || (v2.size() == 1 && v2[0] == 0))) {
if (is == 1) {
cout << "0\n";
return ItoV (0);
} else
return ItoV (0);
}
long long num = 0;
vint re;
for (int i = 0; i < v1.size(); i++) {
for (int j = 0; j < v2.size(); j++) {
num += (long long) v1[i] * v2[j];
if (i + j >= re.size())
re.push_back (0);
num += re[i + j];
re[i + j] = num % mod;
num /= mod;
}
int now = i + v2.size();
while (num) {
if (now >= re.size())
re.push_back (0);
num += re[now];
re[now] = num % mod;
num /= mod;
now++;
}
}
int now = v1.size() + v2.size() - 1;
while (num) {
if (now >= re.size())
re.push_back (0);
num += re[now];
re[now] = num % mod;
num /= mod;
now++;
}
if (is == 1)
out (re);
else
return re;
}
void divi (string str, vint v) {
if (bigger (StoV (str), v) == 0) {
cout << "0\n";
return;
}
vint vec = ItoV (0);
vint vv[10];
for (int i = 0; i < 10; i++)
vv[i] = mult (v, ItoV (i), 0);
bool is = 0;
for (int k = 0; k < str.length(); k++) {
vec = add (mult (vec, ItoV (10), 0), ItoV (str[k] - '0'), 0);
if (is == 0) {
if (bigger (vec, v) == 1) {
for (int i = 9; i >= 0; i--)
if (bigger (vec, vv[i]) == 1) {
cout << i;
vec = sub (vec, vv[i], 0);
break;
}
is = 1;
}
} else {
for (int i = 9; i >= 0; i--)
if (bigger (vec, vv[i]) == 1) {
cout << i;
vec = sub (vec, vv[i], 0);
break;
}
}
}
cout << '\n';
}
int main() {
ios::sync_with_stdio (false), cin.tie (0);
string str1, str2, c;
cin >> str1 >> c >> str2;
if (c == "+")
add (StoV (str1), StoV (str2), 1);
if (c == "-")
sub (StoV (str1), StoV (str2), 1);
if (c == "*")
mult (StoV (str1), StoV (str2), 1);
if (c == "/")
divi (str1, StoV (str2));
}
d427:大數根號
原理可見維基百科
首先先處理整數部分,再處理小數
然後乘法的地方寫錯了,不過因為 $\text{vec2}$ 的長度都只用到 $1$,所以沒差
#pragma GCC optimize("O3")
#include <iostream>
#include <vector>
using namespace std;
const int mod = 1000000000;
bool bigger (vector<int>vec1, vector<int>vec2) {
if (vec2.size() > vec1.size() || vec1 == vec2)
return 0;
if (vec1.size() > vec2.size())
return 1;
for (int i = vec1.size() - 1; i >= 0; i--) {
if (vec1[i] > vec2[i])
return 1;
if (vec1[i] < vec2[i])
return 0;
}
}
vector<int>plu (vector<int>vec1, vector<int>vec2) {
long long num = 0;
vector<int>re;
for (int i = 0;; i++) {
if (i >= vec1.size() && i >= vec2.size() && num == 0)
break;
if (i < vec1.size())
num += vec1[i];
if (i < vec2.size())
num += vec2[i];
re.push_back (num % mod);
num /= mod;
}
return re;
}
vector<int>dec (vector<int>vec1, vector<int>vec2) {
long long num = 0;
int sum = 0;
vector<int>re;
for (int i = 0; i < vec1.size(); i++) {
num = vec1[i] - num;
if (i < vec2.size())
num -= vec2[i];
if (num >= 0)
re.push_back (num), num = 0;
else
re.push_back (mod + num), num = 1;
}
for (int i = re.size() - 1; i >= 0; i--) {
if (re[i] == 0)
sum++;
else
break;
}
re.resize (re.size() - sum);
if (re.size() == 0)
re.push_back (0);
return re;
}
vector<int>mult (vector<int>vec1, vector<int>vec2) {
vector<int>re;
if ( (vec1.size() == 1 && vec1[0] == 0) || (vec2.size() == 1 && vec2[0] == 0)) {
re.push_back (0);
return re;
}
long long num = 0;
for (int i = 0; i < vec1.size(); i++)
for (int j = 0; j < vec2.size(); j++) {
num += (long long) vec1[i] * vec2[j];
if (i + j >= re.size())
re.push_back (0);
num += re[i + j];
re[i + j] = num % mod;
num /= mod;
}
while (num)
re.push_back (num % mod), num /= mod;
return re;
}
vector<int>Int_To_Vec (int n) {
vector<int>re;
re.push_back (n);
return re;
}
int main() {
ios::sync_with_stdio (false), cin.tie (0);
string str;
while (cin >> str) {
vector<int>vec, left;
int now = 0, pos = 0;
bool point = 0;
if (str.length() % 2 == 1)
pos = 1, vec.push_back (str[0] - '0');
else
pos = 2, vec.push_back ( (str[0] - '0') * 10 + str[1] - '0');
left.push_back (0);
while (1) {
left = mult (plu (left, Int_To_Vec (left[0] % 10)), Int_To_Vec (10));
if (point == 0) {
for (int i = 1; i <= 9; i++) {
if (bigger (mult (plu (left, Int_To_Vec (i)), Int_To_Vec (i)), vec) == 1) {
cout << i - 1;
left = plu (left, Int_To_Vec (i - 1));
vec = dec (vec, mult (left, Int_To_Vec (i - 1)));
break;
}
if (i == 9) {
cout << '9';
left = plu (left, Int_To_Vec (9));
vec = dec (vec, mult (left, Int_To_Vec (9)));
}
}
if (pos == str.length()) {
cout << '.';
point = 1;
continue;
}
vec = plu (mult (vec, Int_To_Vec (100)), Int_To_Vec (10 * (str[pos] - '0') + str[pos + 1] - '0'));
pos += 2;
} else {
vec = mult (vec, Int_To_Vec (100));
for (int i = 1; i <= 9; i++) {
if (bigger (mult (plu (left, Int_To_Vec (i)), Int_To_Vec (i)), vec) == 1) {
cout << i - 1;
left = plu (left, Int_To_Vec (i - 1));
vec = dec (vec, mult (left, Int_To_Vec (i - 1)));
break;
}
if (i == 9) {
cout << '9';
left = plu (left, Int_To_Vec (9));
vec = dec (vec, mult (left, Int_To_Vec (9)));
}
}
now++;
if (now == 50)
break;
}
}
cout << '\n';
}
}
我的分享就到這裡結束了,如果喜歡我的 $\text{Blog}$,歡迎追蹤!
留言
張貼留言