消除元素(eliminate.cpp)—CF1375C—1400
时间限制 1s | 空间限制 256M
题目描述:
给定一个长度为 n 的数组 a,初始时它是从1到 n 的排列。每一次操作中,你可以选择一个下标i (1<=i<=n),满足 ai<=ai+1,然后从数组中移除ai或ai+1中的一个(移除后,其余部分将被合并)。
例如,如果你有数组 [1,3,2],你可以选择 i=1(因为 a1<a2),然后要么移除 a1,得到新的数组 [3,2],要么移除 a2,得到新的数组 [1,2]。
通过这些操作,是否可能使得数组的长度变为1?
输入格式:
输入的第一行包含一个整数 t(1<=t<=2*10^4)——测试中的测试用例数量。
每个测试用例的第一行包含一个整数 n(1<=n<=3*10^5) ---- 数组的长度。
每个测试用例的第二行包含n个整数a1,a2,…,an(1<=ai<=n,ai) 两两不相同 ---- 数组的元素。
保证所有测试用例中n的总和不超过 3*10^5。
输出格式:
对于每个测试案例,输出一行结果,如果可以通过上述操作将数组减少到单个元素,则输出YES,如果不可能,则输出NO。
样例输入输出:
样例1输入 | 样例1输出 |
---|---|
4 3 1 2 3 4 3 1 2 4 3 2 3 1 6 2 4 6 1 3 5 | YES YES NO YES |
样例解释:
对于前两个测试案例和第四个测试案例,我们可以按照以下方式进行操作(被加粗的元素是进行操作选择的一对):
[1,2,3]→[1,2]→[1]
[3,1,2,4]→[3,1,4]→[3,4]→[4]
[2,4,6,1,3,5]→[4,6,1,3,5]→[4,1,3,5]→[4,1,5]→[4,5]→[4]
题解:
当a1<an是策略存在,否则不存在
策略:
每次找到一个离 a1最近的一个数 ax,满足 ax>a1,然后我们用 ax消除所有下标在(1,x) 中的数ai,然后这个 ax就来到了 a1 旁边,我们再把 ax 移走。反复重复这个策略,最后成为ax 的一定是 an,最后数组只剩下了a1。
参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int a[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(a[1]>a[n]) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}