题意:
给你两个序列,相邻的数可以合并,问在两个序列执行这样的操作,最后可以是两个序列相等吗?若相等,相等的最大长度又是多少?
思路:
比赛的时候想到模拟。其实很多题,第一眼的思路都是去模拟,比如这次比赛的B题,我摸你了半天还是失败了。可以说,模拟简单直白,容易想到,但往往害死人。
我们直接利用类似前缀和的做法去弄。第一个序列的前缀和是sum1,第二个时sum2,若sum1 < sum2,则由最外层的for循环继续对sum1叠加,若sum2 < sum1,则由for循环内的while循环一直叠加到sum1 <= sum2,若sum1==sum2,则两者均重置为0,然后计数cnt加1。可以用几个例子去尝试理解。
AC code:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3e5 + 10;//我又被欺骗了,模拟害死人
int n = 0,m = 0;
int a[maxn],b[maxn];
int main(){
LL sum1 = 0,sum2 = 0;
scanf("%d",&n);
for(int i = 1;i <= n;++i){
scanf("%d",&a[i]);
sum1 += a[i];
}
scanf("%d",&m);
for(int i = 1;i <= m;++i){
scanf("%d",&b[i]);
sum2 += b[i];
}
if(sum1 != sum2){
printf("-1\n");
return 0;
}
int j = 1,cnt = 0;
sum1 = 0,sum2 = 0;
for(int i = 1;i <= n;++i){//如果第一个序列的和小于第二个时,for循环是的第一个一直加
sum1 += a[i];
while(sum2 < sum1){//第一个序列的和大于第二个时,第二个一直加
sum2 += b[j++];
}
if(sum2 == sum1){//相等就计数加一,和重置为0
sum1 = sum2 = 0;
cnt++;
}
}
printf("%d\n",cnt);
return 0;
}