P10672 【MX-S1-T1】壁垒 题解
前置知识
解法
一个简单的结论:随着前缀长度的增长,出现的数字种类数每次只能增加 \(0\) 或 \(2\)。考虑构造时可以从这里下手。
一种构造方案是这样的:优先让数字种类数增加 \(2\),即先将原先没有出现过的数往前放;接着让数字种类数增加 \(0\),即后将原先出现过的数往后放。
- 同时,也解释了当 \(1 \sim n\) 中出现的数字种类数是奇数时不存在这样的重排方式。
找重复元素时可以借助 unique
函数,但需要注意的是unique
函数对于重复的元素并不是将其删除,而是将其移动赋值,可能会覆盖先前的数,可参考 C++ 手册,故可以使用一个桶来进行手动统计。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
int a[100010],vis[100010];
int main()
{
int n,m,i,j;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[i];
vis[a[i]]++;
}
sort(a+1,a+1+n);
m=unique(a+1,a+1+n)-(a+1);
if(m%2==0)
{
for(i=1;i<=m;i++)
{
vis[a[i]]--;
cout<<a[i]<<" ";
}
for(i=1;i<=n;i++)
{
for(j=1;j<=vis[i];j++)
{
cout<<i<<" ";
}
}
}
else
{
cout<<"-1"<<endl;
}
return 0;
}
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18275565,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。