蓝桥云客 合并数列
0合并数列 - 蓝桥云课
问题描述
小明发现有很多方案可以把一个很大的正整数拆成若干正整数的和。他采取了其中两种方案,分别将他们列为两个数组 {a1, a2, ..., an}
和 {b1, b2, ..., bm}
。两个数组的和相同。
定义一次合并操作可以将某数组内相邻的两个数合并为一个新数,新数的值是原来两个数的和。小明想通过若干次合并操作将两个数组变成一模一样,即 n = m
且对于任意下标 i
满足 a_i = b_i
。请计算至少需要多少次合并操作可以完成小明的目标。
输入格式
输入共3行。
第一行为两个正整数 n, m
。
第二行为 n
个由空格隔开的整数 a1, a2, ..., an
。
第三行为 m
个由空格隔开的整数 b1, b2, ..., bm
。
输出格式
输出共1行,一个整数。
样例输入
4 3
1 2 3 4
1 5 4
样例说明
只需要将 a2
和 a3
合并,数组 a
变为 {1, 5, 4}
,即和 b
相同。
评测用例规模与约定
对于 20% 的数据,保证 n, m ≤ 10^3
。
对于 100% 的数据,保证 n, m ≤ 10^5
,0 < a_i, b_i ≤ 10^5
。
思路:
暴力遍历,双指针
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e5+10;
ll n,m;
ll a[N],b[N];
ll ans = 0;
int main()
{
cin >> n >> m;
for(ll i = 1 ; i <= n ; i++)
cin >> a[i];
for(ll i = 1 ; i <= m ; i++)
cin >> b[i];
ll l = 1,r = 1;
while(l <= n && r <= m)
{
if(a[l] == b[r])
{
l++;
r++;
}
else if(a[l] < b[r])
{
a[l+1] += a[l];
l++;
ans++;
}
else if(a[l] > b[r])
{
b[r+1] += b[r];
r++;
ans++;
}
}
cout << ans;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e5+10;
ll n,m;
ll a[N],b[N];
ll ans = 0;
int main() {
cin >> n >> m;
for (ll i = 1; i <= n; i++) cin >> a[i];
for (ll i = 1; i <= m; i++) cin >> b[i];
ll l = 1, r = 1;
while (l <= n && r <= m) { // 修正循环条件
if (a[l] == b[r]) {
l++;
r++;
} else if (a[l] < b[r]) {
ll sum = a[l];
l++;
while (sum < b[r] && l <= n) { // 合并 a 数组的元素
sum += a[l];
l++;
ans++;
}
r++; // 此时 sum >= b[r]
} else { // a[l] > b[r]
ll sum = b[r];
r++;
while (sum < a[l] && r <= m) { // 合并 b 数组的元素
sum += b[r];
r++;
ans++;
}
l++; // 此时 sum >= a[l]
}
}
cout << ans;
return 0;
}