题目
https://codeforces.com/gym/101775/problem/J
分析
- 说是用长度 3 至 5 的线段覆盖,其实发现 5 以上的都能用 3 至 5 的完成覆盖(6=3*2)。也就是说问题简化为了能否用长度大于等于 3 的线段覆盖。
- 那就差分,加的时候延迟三个长度再加,减的时候立即减,看看是否会出现减到负数的情况,若会出现则说明无法覆盖,没出现则说明可以。注意一下要在最后的位置加一个0以判断最后三个数能否满足。
代码
#include <bits/stdc++.h>
using namespace std;
int n;
int a[200005];
void solve(int iidd)
{
scanf("%d", &n);
for (int i=1; i<=n; i++) scanf("%d", &a[i]);
a[n+1]=0;
long long buf[3]={0};
long long cur=0;
int tmp;
for (int i=1; i<=n+1; i++) {
cur+=buf[2];
for (int i=2; i>0; i--) buf[i]=buf[i-1];
buf[0]=0;
tmp = a[i]-a[i-1];
if (tmp>0) {
buf[0]=tmp;
}
else if (tmp<0) {
cur+=tmp;
if (cur < 0) {
printf("Case #%d: No\n", iidd);
return;
}
}
}
printf("Case #%d: Yes\n", iidd);
}
int main()
{
int ttt;
scanf("%d", &ttt);
for (int tt=1; tt<=ttt; tt++) {
solve(tt);
}
return 0;
}
/*
2
13
1 2 2 1 0 0 0 0 0 0 0 0 0
13
1 1 1 1 0 1 1 0 0 0 0 0 0
*/