C - Array in the Pocket (ZOJ - 4102)
题意:给你数组a,问你重新排列这个数组得到b,能使a[i]!=b[i]字典序最小的b数组。
思路:贪心其实可以做!!!
3 2 1 5 4 4 4 4 7
手动模拟这个例子,很快可以得出
3 2 1 5 4 4 4 4 7
1 3 2 4 5 7 x x x
我们发现此时只有4能填,但是这个位置又不能填4,那么就得找一个位置去填这个4,很明显,在这个位置之前的我们按照贪心思路填的是最优的,没有到万不得已绝对不会去改变它,所以我们找此刻位置之后的能填4的,序列变成
3 2 1 5 4 4 4 4 7
1 3 2 4 5 7 x x 4
此时都后面能填的都填了,没有办法了,已经到了万不得已的情况了,就只能动前面的了,贪心的想,肯定是动越靠后越优,并且此时上方和下方都不能是4。所以我们可以取3 2来填,并且这个3 2应该按字典序最小的填(不按字典序也可以,往下看就知道了)。 序列变成
3 2 1 5 4 4 4 4 7
1 4 4 4 5 7 2 3 4
这种情况满足了条件,但并没有满足最小,此时对于4这些位置我们并不是按贪心思路填下去的,所以应该再把4的这些位置重排序一下,序列变成
3 2 1 5 4 4 4 4 7
1 4 4 4 2 3 5 7 4
这便是最优解。
复杂度O(k * n * log(n))
/*
▄███████▀▀▀▀▀▀███████▄
░▐████▀▒▒▒▒▒▒▒▒▒▒▀██████▄
░███▀▒▒▒ACCEPTED▒▒▒▒▀█████
░▐██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████▌
░▐█▌▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████▌
░░█▒▄▀▀▀▀▀▄▒▒▄▀▀▀▀▀▄▒▐███▌
░░░▐░░░▄▄░░▌▐░░░▄▄░░▌▐███▌
░▄▀▌░░░▀▀░░▌▐░░░▀▀░░▌▒▀▒█▌
░▌▒▀▄░░░░▄▀▒▒▀▄░░░▄▀▒▒▄▀▒▌
░▀▄▐▒▀▀▀▀▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒█
░░░▀▌▒▄██▄▄▄▄████▄▒▒▒▒█▀
░░░░▄██████████████▒▒▐▌
░░░▀███▀▀████▀█████▀▒▌
░░░░░▌▒▒▒▄▒▒▒▄▒▒▒▒▒▒▐
░░░░░▌▒▒▒▒▀▀▀▒▒▒▒▒▒▒▐
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int INF=1e9+7;
const double eps=1e-6;
const long long mod=1e9+7;
typedef long long ll;
typedef pair<ll,ll>p;
int T,flag,n;
set<int>s;
int a[N],cnt[N],ans[N];
vector<int>pos[N],res[N];
int main() {
cin>>T;
while(T--) {
flag=0,s.clear();
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]),cnt[i]=0,pos[i].clear(),res[i].clear(),ans[i]=0;
for(int i=1; i<=n; i++) {
cnt[a[i]]++;
if(cnt[a[i]]>=n/2+1)
flag=1;
s.insert(a[i]);
}
if(flag) {
printf("Impossible\n");
continue;
}
for(int i=1; i<=n; i++) {
auto val=*s.begin();
if(s.size()==1&&val==a[i]) {
///把当前的数字分配给后面
vector<int>poss,tmp;
for(int j=i+1; j<=n; j++) {
if(a[j]!=val) {
ans[j]=val;
cnt[val]--;
}
}
for(int j=i; j<=n; j++) {
///后面有多少个不符合的位置
if(ans[j]==0&&a[j]==a[i])
poss.push_back(j);
}
for(int j=i-1; j>=1; j--) {
///从前面找符合的位置
if(cnt[val]==0)
break;
if(ans[j]!=val&&val!=a[j]) {
tmp.push_back(ans[j]);
ans[j]=val;
cnt[val]--;
}
}
int len=poss.size();
for(int j=0; j<len; j++) {
ans[poss[j]]=tmp[j];
}
poss.clear(),tmp.clear();
s.erase(val);
break;
} else {
auto it=s.begin();
if(val==a[i]) {
++it;
}
val=*it;
ans[i]=val;
//cout<<i<<" "<<val<<endl;
cnt[val]--;
if(cnt[val]==0)
s.erase(val);
}
}
for(int i=1; i<=n; i++) {
pos[a[i]].push_back(i);
res[a[i]].push_back(ans[i]);
}
for(int i=1; i<=n; i++) {
if(pos[i].size()==0)
continue;
sort(pos[i].begin(),pos[i].end());
sort(res[i].begin(),res[i].end());
int len=pos[i].size();
for(int j=0; j<len; j++) {
ans[pos[i][j]]=res[i][j];
}
}
for(int i=1; i<=n; i++) {
printf("%d%c",ans[i]," \n"[i==n]);
}
}
}
/*
1 9
3 2 1 5 4 4 4 4 7
*/