原题:
D. Vasya and Arrays
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vasya has two arrays A and B of lengths n and m, respectively.
He can perform the following operation arbitrary number of times (possibly zero): he takes some consecutive subsegment of the array and replaces it with a single element, equal to the sum of all elements on this subsegment. For example, from the array [1,10,100,1000,10000] Vasya can obtain array [1,1110,10000], and from array [1,2,3] Vasya can obtain array
[6].
Two arrays A and B are considered equal if and only if they have the same length and for each valid i Ai=Bi.
Vasya wants to perform some of these operations on array A, some on array B, in such a way that arrays A and B
become equal. Moreover, the lengths of the resulting arrays should be maximal possible.
Help Vasya to determine the maximum length of the arrays that he can achieve or output that it is impossible to make arrays A and Bequal.
Input
The first line contains a single integer n (1≤n≤3⋅10^5) — the length of the first array.
The second line contains n integers a1,a2,⋯,an(1≤ai≤10^9) — elements of the array A.
The third line contains a single integer m (1≤m≤3⋅10^5) — the length of the second array.
The fourth line contains m integers b1,b2,⋯,bm (1≤bi≤10^9) - elements of the array B.
Output
Print a single integer — the maximum length of the resulting arrays after some operations were performed on arrays
A and B in such a way that they became equal.
If there is no way to make array equal, print “-1”.
Examples
input
5
11 2 3 5 7
4
11 7 3 7
output
3
input
2
1 2
1
100
output
-1
input
3
1 2 3
3
1 2 3
output
3
中文:
给你两个序列,给你一个操作,问你最少多少步操作可以使这两个序列相同,两个序列相同就是这两个序列长度相同而且对应下标的数字相同。
操作是可以将相邻的两个数字合并,例如[1,2,3,4,5],可以将2和3合并为5,结果是[1,5,4,5]。
如果不能通过操作使得两个序列相同,输出-1.
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=300005;
int n,m;
ll a[maxn],b[maxn],sa[maxn],sb[maxn];
int main()
{
ios::sync_with_stdio(false);
while(cin>>n)
{
memset(sa,0,sizeof(sa));
memset(sb,0,sizeof(sb));
for(int i=1;i<=n;i++)
{
cin>>a[i];
sa[i]=sa[i-1]+a[i];
}
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>b[i];
sb[i]=sb[i-1]+b[i];
}
if(sa[n]!=sb[m])
{
cout<<-1<<endl;
continue;
}
if(n==1||m==1)
{
if(sa[n]==sb[m])
cout<<1<<endl;
else
cout<<-1<<endl;
continue;
}
int i=1,j=1,flag=0,ans=n;
while(true)
{
if(i==n&&j==m)
break;
if(a[i]==b[j])
{
if(i<n)
i++;
if(j<m)
j++;
}
else
{
int pa=i,pb=j;
while(sa[i]-sa[pa-1]!=sb[j]-sb[pb-1])
{
if(sa[i]-sa[pa-1]>sb[j]-sb[pb-1])
{
if(j==m)
{
flag=-1;
break;
}
j++;
}
if(sa[i]-sa[pa-1]<sb[j]-sb[pb-1])
{
if(i==n)
{
flag=-1;
break;
}
i++;
}
}
ans-=(i-pa);
if(i<n)
i++;
if(j<m)
j++;
}
if(flag==-1)
break;
}
if(flag==-1)
cout<<-1<<endl;
else
cout<<ans<<endl;
}
return 0;
}
思路:
首先可以判断的是,如果两个序列A和B的总和不相同,那么肯定不能通过操作使得两个序列相等。
如果两个序列的总和相同,可以设置两个下标i和j,分别指向序列A和序列B的开头,依次判断下标对应值是否相等,如果相等,下标前移。否则,指向的元素值小的那个下标向前累加,如果累加和超过另一个下标所指向的元素,则另外一个下标也向前累加,直到两个累加和相同。如果两个下标移动到最后也没使两个累加和相同,那么输出-1,否则计数累加过的元素个数再减去1就是答案。