CF1253A Single Push 题解
lmndiscyhyzdxss · · 题解
题目大意
给出一个操作:在
例如:
题目分析
- 这道题首先想到的是暴力枚举 , 是指针一个指向数组
a ,一个指向数组b ,分别做差,但时间复杂度为\left(n^2\right) - 我们可以用数组
a 与数组b 做差,得到c 数组,然后用一种类似尺取法的方法进行一个一个判断
正确的情况应该是:\begin{matrix}\underbrace{0,0,0\cdots0}\\l-1\end{matrix} $ $ \begin{matrix}\underbrace{h,h,h\cdots h}\\ l \thicksim r \end{matrix} $ $ \begin{matrix}\underbrace{0,0,0\cdots0}\\r+1\end{matrix} 我们要做什么事呢:
- 判断是否为负数,因为零不行
- 判断是否当前还是 0 或跟上一个一样,这样可以
- 储存第一个不是 0 的数
- 输出
我构造了一个前缀和数组, 可以快速判断后面是否都是零,不用三个循环了 不像前面两位大佬们那么麻烦了,代码比较精炼AC代码
#include<bits/stdc++.h> using namespace std; int t,n,a[100010],b[100010],c[100010],d[100010],l,p; int main() { cin>>t; while(t--) { scanf("%d",&n),p=1,l=0; for(int i=1;i<=n;i++)scanf("%d",&a[i]),d[i]=0; for(int i=1;i<=n;i++)scanf("%d",&b[i]); for(int i=1;i<=n;i++)c[i]=b[i]-a[i],d[i]=d[i-1]+c[i]; for(int i=1;i<=n;i++) { if(c[i]<0){printf("NO\n");p=0;break;}//不可能加负数 else if(c[i]==0&&l==0||l!=c[i]&&c[i]==0&&d[n]-d[i]==0||l==c[i])continue;//如果当前还是0或跟上一个一样 else if(l==0&&c[i]!=0)l=c[i];//第一个不是0的数 else {printf("NO\n");p=0;break;}//否则不成立 } if(p==1)printf("YES\n"); } return 0; }