https://csacademy.com/contest/round-19/#task/smallest-array-permutation

$N$個の要素を持つ配列が与えられる.同じ要素が隣り合わず,辞書順で最小のものを求める.

辞書順最小にしたいので,小さい数から順番に並べたいが,前回置いたものと同じ数を置くことは出来ないため,前回置いた数以外の最小の数を並べていく.同じ数が隣り合わないために,まだ決めていない要素数が奇数の時かつ,同じ要素が$\frac{要素数+1}{2}$ある時は,$1$個飛ばしで並べなければならないことに注意する.

#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,k,n) for(int i=k;i<(int)(n);i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define INF 1<<30
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int main() {
	int n;
	cin >> n;

	map<int, int> m;
	rep(i, n) {
		int x;
		cin >> x;

		m[x]++;
	}

	priority_queue<P> que;
	each(it, m) {
		if(it->second > (n + 1) / 2) {
			cout << -1 << endl;
			return 0;
		}

		que.push(mp(it->se, -it->fi));
	}

	int len = n, pre = -1;
	vector<int> ans;

	while(que.size()) {
		int cnt = que.top().fi;
		int id = -que.top().se;

		while(m.count(id) == 0) {
			que.pop();
			cnt = que.top().fi;
			id = -que.top().se;
		}

		while(true) {
			cnt = m[id];
			que.pop();

			if(!que.size()) break;

			if(que.top().fi <= cnt) {
				que.push(mp(cnt, -id));
				break;
			} else {
				cnt = que.top().fi;
				id = -que.top().se;
			}
		}

		if(len % 2 == 1) {
			if(cnt == (len + 1) / 2) {
				m[id]--;
				if(m[id] == 0) m.erase(id);

				pre = id;
				ans.push_back(id);
				que.push(mp(cnt - 1, -id));
			} else {
				map<int, int>::iterator it = m.begin();

				if(it->fi == pre) it++;
				m[it->fi]--;
				if(m[it->fi] == 0) m.erase(it->fi);

				pre = it->fi;
				ans.push_back(it->fi);
			}
		} else {
			map<int, int>::iterator it = m.begin();
			if(it->fi == pre) it++;
			m[it->fi]--;
			if(m[it->fi] == 0) m.erase(it->fi);

			pre = it->fi;
			ans.push_back(it->fi);
		}

		len--;
		if(len == 0) break;
	}

	rep(i, ans.size()) {
		if(i) cout << " ";
		cout << ans[i];
	}
	cout << endl;

	return 0;
}