D. Constructing the Array(排序&递归)

D. Constructing the Array(排序&递归)

思路:因为只分成了 n n 个区间,对于分区间我们可以用递归实现,然后根据题目要求进行排序即可,因此我们可以用 p a i r pair 来储存区间长度和当前的中点下标。

对于排序方式,我们可以用将区间长度取相反数然后从小到大排,或者自己写一个自定义排序。

时间复杂度: O ( n l o g n ) O(nlogn)

#include <bits/stdc++.h>
using namespace std;
const int N=2e6+5;
pair<int, int> a[N];
int b[N];
void fun(int l,int r){
	if(l>r) return;
	int m=(l+r)>>1;
	a[m].first=l-r;//因为pair默认按first升序排,所以存入l-r 让区间长度最大的在前面 
	a[m].second=m;//当first相等,就按second排 
	fun(l,m-1);
	fun(m+1,r); 
}
int main()
{
	int t, n;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		fun(1,n);
		sort(a+1,a+n+1);
		for(int i=1;i<=n;i++) b[a[i].second]=i;
		for(int i=1;i<=n;i++) printf("%d ",b[i]);
		puts("");
	} 
	return 0;
}

官方解法 : s e t + set+ 自定义排序
AC代码:

#include <bits/stdc++.h>
using namespace std;
struct cmp {
	bool operator() (const pair<int, int> &a, const pair<int, int> &b) const {
		int lena = a.second - a.first + 1;
		int lenb = b.second - b.first + 1;
		if (lena == lenb) return a.first < b.first;
		return lena > lenb;
	}
};
int main() {
	int t;
	cin >> t;
	while (t--) {
		int n;
		cin >> n;
		set<pair<int, int>, cmp> segs;
		segs.insert({0, n - 1});
		vector<int> a(n);
		for (int i = 1; i <= n; ++i) {
			pair<int, int> cur = *segs.begin();
			segs.erase(segs.begin());
			int id = (cur.first + cur.second) / 2;
			a[id] = i;
			if (cur.first < id) segs.insert({cur.first, id - 1});
			if (id < cur.second) segs.insert({id + 1, cur.second});
		}
		for (auto it : a) cout << it << " ";
		cout << endl;
	}
	
	return 0;
}
原创文章 201 获赞 165 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/106133937