题解:CF1941B Rudolf and 121
题意
给出一个由 个整数组成的数组 ,元素的编号从 到 。对于每一次操作,选择下标 ,执行以下赋值操作。
是否可以用这个操作,使整个数组变为零。
思路
题目中的操作是修改 个元素的值,考虑对原序列差分。题目中的每一次操作就相当于将差分数组 以及 减 ,将 与 加 。最终的目标是使得 变为全零。
那么对于任何一个 ,如果 是一个正数,那么就必须选择 执行 次操作,因为在 后只有 还能减小 的值,而且也只能进行 次操作,因为在操作就会使 变为负数。如果 此时为负数,那么就不可能在让它变为正数了,所以不可以使整个 数组变为零。
那么我们从 到 遍历一遍所有 然后按照刚刚的思路操作就可以了。
最后检查 数组如果不全为零,那么就不可以使整个 数组变为零。
Code
#include <iostream>
using namespace std;
const int N=1e5*2+10;
int a[N],b[N];
int n;
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) if(a[i]<0)
{
puts("NO");
continue;
}
b[1]=a[1];
for(int i=2;i<=n;i++) b[i]=a[i]-a[i-1];
bool flag=0;
for(int i=2;i<n;i++)
{
if(b[i-1]<0) break;
b[i]-=b[i-1];
b[i+2]+=b[i-1];
b[i+1]+=b[i-1];
b[i-1]-=b[i-1];
}
for(int i=1;i<=n;i++)
if(b[i]!=0) flag=1;
if(flag) puts("NO");
else puts("YES");
}
return 0;
}

浙公网安备 33010602011771号