题目链接
题目大意
真难读
问给定的序列能不能用题中所给的算法生成。
比如,题目中举的例子:原序列a: [ 2 3 * * 1 ],先得出 r 数组 [ 3, 3 ,3 ,4 , * ] 。r 数组的意思是:原序列当前位置右边第一个空格的位置,比如原序列 a 索引为1的位置的右边第一个空位是 3。索引为2的位置的右边第一个空位是 3。索引为4的位置的右边第一个空位是它自己 4 。索引为5的位置的右边没有空位 标记为 *
然后得出count数组,对 r 数组中的出现的数字计数 为 [ 0 , 0 , 3 , 1 ,0 ]。3代表3在 rrr 里面出现了3次。然后count数组中最大的数字出现的位置,就是原序列中选择的位置。这里count数组中索引为3的位置数字最大为3,所以原序列选择第3个位置填充数字。
题目思路
其实差不多懂了怎么判断,还是没写出来qwq
假设从 1到n 构造一个序列,在放 i 的时候,如果 i - 1 的右边还有空位,就必须放在 i -1 后面。如果 i -1 右边一位没有空位了,就可以任意放。比如,[* * 2 * 1 ],放3的时候,就只能是 [* * 2 3 1] 。然后 444 就可以随便放,因为3的右边一位已经没有空位了。
所以就遍历一遍看每个数字的位置是否合法。从 1 到 n,检查数字 i 是否合理的时候,这个数字 i 的右边一位,要么是 i +1 ,要么就是被 小于 i 的数字填过了。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int t,n,a[maxn];
int main(){
scanf("%d",&t);
while(t--){
bool flag=1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n-1;i++){
if(2<=a[i+1]-a[i]){
flag=0;
printf("No\n");
break;
}
}
if(flag){
printf("Yes\n");
}
}
return 0;
}
参考链接:https://blog.csdn.net/cheng__yu_/article/details/105727930