首先set贪心取最小,但是没填入B集合里的个数最多的元素加上A集合中待填的该元素,不可多于剩下的元素数,否则要取该元素。
1 1 2 2 3 3 3
2
如果第二个元素填2 则剩下的3的个数,加上A里的剩下的3的个数多于(6/2)(6是剩下的元素个数)
所以第二个元素只能填3
当然,如果一开始就有元素多于n/2,输出Impossible.
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+10;
int a[M],b[M];
int c[M],cc[M];
typedef pair<int,int> P;
set<P> s1,s2;
set<P>::iterator it,mx;
int main(){
int t,n;
cin>>t;
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
a[i]=b[i]=c[i]=cc[i]=0;
}
s1.clear();s2.clear();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
c[a[i]]++;cc[a[i]]+=2;
}
for(int i=1;i<=n;i++){
if(c[i]){
s1.insert(P(i,c[i]));
s2.insert(P(cc[i],i));
}
}
//int temp=(*(--s2.end()))->first;
it=s2.end();
it--;
int temp=it->first;
if(temp>n){
printf("Impossible\n");
continue;
}
for( int i=1;i<=n;i++){
s2.erase(P(cc[a[i]],a[i]));
s2.insert(P(--cc[a[i]],a[i]));
it=s1.begin();
mx=s2.end();
mx--;
if(mx->first==n-i+1){
b[i]=mx->second;
}
else {
if(a[i]==it->first)it++;
b[i]=it->first;
}
s1.erase(P(b[i],c[b[i]]));
c[b[i]]--;
s2.erase(P(cc[b[i]],b[i]));
cc[b[i]]--;
if(c[b[i]])s1.insert(P(b[i],c[b[i]]));
if(cc[b[i]])s2.insert(P(cc[b[i]],b[i]));
}
cout<<b[1];
for(int i=2;i<=n;i++){
printf(" %d",b[i]);
}
printf("\n");
}
}