1. 程式人生 > 其它 >題解 CF1557B 【Moamen and k-subarrays】

題解 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