hihocoder 1356 分隔相同整数(贪心)

描述
给定一个包含N个整数的数组A。你的任务是将A重新排列,使得任意两个相等的整数在数组中都不相邻。

如果存在多个重排后的数组满足条件,输出字典序最小的数组。

这里字典序最小指:首先尽量使第一个整数最小,其次使第二个整数最小,以此类推。

输入
第一行包含一个整数N,表示数组的长度。(1 <= N <= 100000)

第二行包含N个整数,依次是 A1, A2, … AN。(1 <= Ai <= 1000000000)

输出
输出字典序最小的重排数组。如果这样的数组不存在,输出-1。

样例输入
4
2 1 3 3
样例输出
1 3 2 3



xnum2num>n,nxxfalse
2numnx
mapset


代码:

#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")

using namespace std;
#define   MAX           100005
#define   MAXN          1000005
#define   maxnode       205
#define   sigma_size    26
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   lrt           rt<<1
#define   rrt           rt<<1|1
#define   middle        int m=(r+l)>>1
#define   LL            long long
#define   ull           unsigned long long
#define   mem(x,v)      memset(x,v,sizeof(x))
#define   lowbit(x)     (x&-x)
#define   pii           pair<int,int>
#define   bits(a)       __builtin_popcount(a)
#define   mk            make_pair
#define   limit         10000

//const int    prime = 999983;
const int    INF   = 0x3f3f3f3f;
const LL     INFF  = 0x3f3f;
const double pi    = acos(-1.0);
const double inf   = 1e18;
const double eps   = 1e-4;
const LL    mod    = 1e9+7;
const ull    mx    = 133333331;

/*****************************************************/
inline void RI(int &x) {
      char c;
      while((c=getchar())<'0' || c>'9');
      x=c-'0';
      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
 }
/*****************************************************/ 

int a[MAX];
map<int,int> ma;
set<pii> s;
int main(){
    int n;
    cin>>n;
    ma.clear();s.clear();
    for(int i=0;i<n;i++) scanf("%d",&a[i]),ma[a[i]]++;
    for(map<int,int>::iterator it=ma.begin();it!=ma.end();it++){
        s.insert(mk(-it->second,it->first));
    }
    int flag=0;
    for(int i=0;i<n;i++){
        map<int,int>::iterator it=ma.find(s.begin()->second);
        if(it->second*2>n-i){
            if(i==0||a[i-1]!=it->first){
                a[i]=it->first;
            }
            else{
                flag=-1;
                break;
            }
        }
        else{
            it=ma.begin();
            if(i==0||it->first!=a[i-1]) a[i]=it->first;
            else it++,a[i]=it->first;
        }
        s.erase(mk(-it->second,it->first));
        it->second--;
        if(it->second!=0) s.insert(mk(-it->second,it->first));
        else ma.erase(it);
    }
    if(flag==-1) cout<<flag<<endl;
    else{
        for(int i=0;i<n;i++){
            printf("%d",a[i]);
            if(i==n-1) printf("\n");
            else printf(" ");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值