前置知识
高精度加法
思路
模拟手动加法计算即可。
例如计算:567 + 28
先个位相加: 7 + 8 = 15,所以结果的个位是5,向十位进 1
再十位相加: 6 + 2 + 1(进位)= 9, 所以十位是 9,向百位进 0
再百位相加: 5 + 0 = 5, 所以结果的百位是 5
综上,计算结果为 595
算法
计算 567 + 28
用 a, b 两个字符串存储输入。a = 567, b = 28
为了方便计算,将两个数分别 倒序 存放在 A, B 两个整数数组中。 A = [7, 6, 5], B = [8, 2]
新建整数数组 C 保存结果,整型变量 t 保存进位,初始 t = 0.
将各个位上的数字相加,求出结果对应位上的数字和进位。
例如对个位计算: A[0] + B[0] = 7 + 8 = 15, 结果个位上是 5, 进位是 1. 所以 C[0] = 5, 进位 t = 1
最后把结果数组 C 中就保存了计算倒序结果,倒序输出就是答案
本题思路
首先用高精度加法计算出两个大整数的和。
然后我们直接遍历求出最大位和最小位即可,但是需要注意的是题目要求如果有多个最大/最小位我们需要找最近的两个作为答案输出。
这样我们就需要把多个最大/最小位置存下来,然后遍历一下求出位差的最小值。
但这个题目感觉有点抽象,位置 和 的位距离居然是 ,我感觉有点抽象了,但是最小位置差又是 0。
不过好在题目也说了,如果结果中所有数字都相同,则差距为 0,这样我们最后再和 0 取个 max 就行。
但是这样复杂度其实比较高,假设最大位置和最小位置的数组长度分别为 ,那么我们实际上的复杂度为 ,可以认为是 ,这样的话 的数据是可以轻松卡掉我们的。
实际上最后我们的代码还可以优化一下,就是最后求最小距离的时候可以枚举一个数组的元素,然后二分找到另一个数组中最近的元素,这样可以把复杂度降低到 ,但这题数据比较水,直接暴力枚举就过了。
吐槽:算法题不给数据范围都是耍流氓!
参考代码
vector<int> add(vector<int> &A, vector<int> &B){
reverse(A.begin(), A.end());
reverse(B.begin(), B.end());
vector<int> res;
int t = 0;
int i;
for(i = 0 ; i < max(A.size(), B.size()) ; i ++) {
if(i < A.size()) t += A[i];
if(i < B.size()) t += B[i];
res.push_back(t % 10);
t /= 10;
}
if(t) res.push_back(t % 10);
reverse(res.begin(), res.end());
return res;
}
int solution(std::string a, std::string b) {
// Please write your code here
vector<int> A, B;
for(int i = 0 ; i < a.size() ; i ++) A.push_back(a[i] - '0');
for(int i = 0 ; i < b.size() ; i ++) B.push_back(b[i] - '0');
auto C = add(A, B);
// for(auto x : C)
// cout << x;
// cout << endl;
int maxv = -1, minv = 10;
vector<int> mxp, mip;
for(int i = 0 ; i < C.size() ; i ++) {
int x = C[i];
if(maxv < x) {
maxv = x;
mxp.clear();
mxp.push_back(i);
} else if(maxv == x) mxp.push_back(i);
if(minv > x) {
minv = x;
mip.clear();
mip.push_back(i);
} else if(minv == x) mip.push_back(i);
}
int ans = 1e9;
for(auto x : mxp)
for(auto y : mip)
ans = min(ans, max(0, abs(x - y) - 1));
// cout << ans << endl;
return ans;
}