题解 CF1557B 【Moamen and k-subarrays】

CF1557B Moamen and k-subarrays

题目大意:

给定一个大小为 \(n\) 的数组。你可以将其分为 \(k\) 个子数组,并按照每个子数组的字典序重新排列这些子数组,再顺次拼接,得到一个新的数组。问是否存在一种划分子数组的方案,使得重新拼接后的数组是单调不降的?

solution:

我们可以先将原数组排好序,用有序的数组与原数组比较。我们发现,两个可以在一个子数组里的数在有序数组里一定是相邻的。所以我们检查原数组,看 \(a_i\)\(a_{i+1}\) 是否是相邻的即可,用一个类似离散化的写法。

代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=3e5+5;
int a[N],c[N];
struct node{
	int x,w;
}b[N];
inline bool cmp(node p,node q){ return p.w<q.w; }
int main(){
	int T; scanf("%d",&T);
	while(T--){
		int n,k; scanf("%d%d",&n,&k);
		int ans=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			b[i].w=a[i];//保存大小,用来排序
			b[i].x=i;//保存位置
		}
		sort(b+1,b+n+1,cmp);//排序
		for(int i=1;i<=n;i++){
			a[b[i].x]=i;//将这个数标记成第 i 
		}
		for(int i=1;i<n;i++){
			if(a[i]==a[i+1]-1);//看与它右面的数是不是相邻的
			else ans++;//否则需要分的组数++
		}
		if(ans>=k) puts("No");//这里 ans其实应该从 1 开始,我这里是0,所以是≥
		else	   puts("Yes");
	}
	return 0;
}

End

posted @ 2021-08-13 15:56  Mr_think  阅读(58)  评论(0)    收藏  举报