Codeforces Round #794 (Div. 1) A

原题链接:https://codeforces.com/contest/1685/problem/A

题目

给定序列a,将a重新排序得到环形序列b(即\(b_0=b_n\)),使其对于任意i满足:

  • \(b_{i−1}<b_i>b_{i+1}\)

或者

  • \(b_{i−1}>bi<b{i+1}\)

换句话而言,\(b\)排列在一个圆圈上,是否使每个数字都严格大于其邻居或严格小于其邻居?

分析

如果n是奇数,则一定无解。

首先将序列a进行排序。

不考虑数字重复,则易得序列\((a_1,a_{m+1},a_2,a_{m+2},…,a_m,a_{2m})\)一定成立。

考虑数字重复的话,如果重复数字大于\(n/2\)个,则一定不成立,得到序列一定会有重复数字。

如果重复数字等于\(n/2\)的话,则需要考虑是否是最大、最小的数字了,除非是最大或最小的数字可以构成一大一小的序列顺序,否则都无解。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
	int tc;
	cin >> tc;
	while(tc--) {
		int n;
		cin >> n;
		vector<ll>a(n);
		for(auto &i:a)
			scanf("%lld",&i);
		int flag = 1;
		if(n%2)
			flag = 0;
		int cnt = 1;
		sort(a.begin(),a.end());
		for(int i = 1 ; i < n ; i++) {
			if(a[i] == a[i-1])
				cnt++;
			else cnt = 1;
			if(cnt*2>n)
				flag = 0;
			if(cnt*2==n && i >= n/2 && i != n-1)
				flag = 0;
		}
		if(flag==1) {
			cout << "YES"<< endl;
			vector<ll>ans;
			int l = 0, r = 0, mid = n/2;
			for(int i = 0 ; i < n ; i++) {
				if(i%2) {
					ans.push_back(a[mid+r++]);
				} else ans.push_back(a[l++]);
			}
			for(int i = 0 ; i < n ; i++)
				cout << ans[i] << " ";
			cout << endl;
		} else {
			cout << "NO" << endl;
		}
	}
}

posted @ 2022-06-05 15:07  seekerHeron  阅读(46)  评论(0)    收藏  举报