题目传送门
题目大意
给你 \(x\) 个 \(0\),\(y\) 个 \(1\),\(z\) 个 \(2\),让你构造一个序列 \(a\) 满足对于任意 \(i(1\le i\le x+y+z)\) 都有 \(a_{i+1}\) 和 \(a_{i-1}\) 中小于 \(a_{i}\) 的数量等于 \(a_{i}\),特别的 \(a_{0}=a_{x+y+z},a_{x+y+z+1}=a_{1}\),判断是否可以构造。
Solution(贪心)
首先我们发现最后一个数的后面那一个又变成第一个了,第一个前面哪一个又变成后面那一个了,所以我们可以把它当做一个环来考虑。然后我们可以想到无论在 \(0\) 左右两边放什么都是合法的,因为没有比 \(0\) 还小的了;\(1\) 的旁边一定存在一个 \(0\),因为要保证有一个数比它小,那只能是 \(0\);\(2\) 的左右两边只要不是 \(2\) 就行,因为 \(2\) 要严格保证左右两边都小于它,所以一定不会有两个 \(2\) 挨在一块。
那么由此我们继续推出两个 \(0\) 中间能放什么:
- 最多放两个 \(1\):因为 \(1\) 需要左右两边必须有一个 \(0\),但是如果在两个 \(0\) 之间放三个及以上的 \(1\) 无法保证上面的前提,所以最多只能放两个 \(1\),那么就可以推出 \(x\) 个 \(0\) 中只能放 \(2x\) 个 \(1\),即 \(2x \ge y\)
- 最多放一个 \(2\):因为 \(2\) 需要左右两边都不能为 \(2\),如果在两个 \(0\) 之间存在两个及以上的 \(2\),那么在它们之间只能用 \(1\) 来隔开,但是这就不满足 \(1\) 左右两边必须有 \(0\) 的前提,所以最多放一个 \(2\),那么可以推出 \(x\) 个 \(0\) 中只能放 \(x\) 个 \(2\),即 \(x \ge z\)
- 如果 \(z=0\) 时,如果 \(y\) 是奇数时一定会存在有一个 \(1\) 单独存在的情况,但这是不允许的,因为这样这个 \(1\) 的左右两边都是 \(0\),那么比它小的就有两个,不符合前提,所以此时也是无解,即 \(z=0,\frac{y}{2}\notin\mathbb{N}^+\) 时。
于是我们得到了以下三条限制条件:
- \(2x \ge y\)
- \(x \ge z\)
- \(z=0,\frac{y}{2}\in\mathbb{N}^+\)
推出这个式子本题就结束了
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {int x=0,f=1;char c=getchar();while(c<'0' || c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0' && c<='9') {x=x*10+c-'0';c=getchar();}return x*f;
}
int T=read();
signed main(){while(T--){int x=read(),y=read(),z=read();if(z==0 && (x*2<y || y%2==1))//第三个限制条件 puts("No");else if(x<z || x*2<y)//第一和二个限制条件 puts("No");elseputs("Yes");}return 0;
}