Character Distance(思维、模拟)4星
题意:
给你一个有 n n n个元素的序列,要求选择其中任意至少一个数,使对于这个数在序列中的位置间隔恰好为 m ( 1 ≤ i < j , a i = a j = x , m ≤ j − i ) m(1\leq i< j,a_i=a_j=x,m\leq j-i) m(1≤i<j,ai=aj=x,m≤j−i)且要求序列满足字典序最小,若无法满足输出-1
1 ≤ n , m ≤ 1 0 6 1\leq n,m\leq 10^6 1≤n,m≤106
题解:
只需要找到一个数让他满足上述条件即可
-
当有元素的出现次数为1时,直接输出 s o r t sort sort后的序列即可
-
其他情况
p o s pos pos为元素的首位置(排序后), c n t cnt cnt为个数
- 对于一个元素x,若满足 p o s + ( c n t − 1 ) ∗ m < = m pos+(cnt-1)*m<=m pos+(cnt−1)∗m<=m,则当尽可能选择后面的元素使可以使字典序尽可能小
- 对于其他情况—— p o s + ( c n t − 1 ) ∗ m > n & & 1 + ( c n t − 1 ) ∗ m ≤ n pos+(cnt-1)*m>n\&\& 1+(cnt-1)*m\leq n pos+(cnt−1)∗m>n&&1+(cnt−1)∗m≤n时,当第一个 x x x的位置越靠后时字典序越小
- 若 x x x都不满足上述情况则为输出-1
#include<bits/stdc++.h>
#define endl '\n'
#define x first
#define y second
#define int long long
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=1e6+10;
int n,m;
int g[N];
int ans1[N],ans2[N];
map<int,int>mp;
bool check(int ans1[],int ans2[]){
for(int i=1;i<=n;i++){
if(ans1[i]>ans2[i]) return false;
else if(ans1[i]<ans2[i]) return true;
}
return true;
}
void solve(){
cin>>n>>m;
mp.clear();
for(int i=1;i<=n;i++){
cin>>g[i];
ans1[i]=ans2[i]=0;
if(!mp.count(g[i])) mp[g[i]]=1;
else mp[g[i]]++;
}
int mi=N;
sort(g+1,g+1+n);
for(auto [x,y]:mp){
if(y==1){
for(int i=1;i<=n;i++) cout<<g[i]<<' ';
cout<<endl;
return ;
}
}
int f1=0,pos1=-1;//第一种情况,从pos往后插
for(int i=n;i>=1;i--){
int j=i-1;
while(g[j]==g[i]&&j>=1) j--;
i=j+1;
if(i+(mp[g[i]]-1)*m<=n){
pos1=g[i],f1=1;
int cnt=mp[g[i]],t=i;
while(cnt--){
ans1[t]=g[i];
t+=m;
}
break;
}
}
if(f1){
for(int i=1,j=1;i<=n;i++){
if(g[i]==pos1) continue;
while(ans1[j]&&j<=n) j++;
ans1[j++]=g[i];
}
}
int pos2=0,f2=0,cnt=N;//第二种情况,从n往前插
for(int i=1;i<=n;i++){
if(i+(mp[g[i]]-1)*m>n&&1+(mp[g[i]]-1)*m<=n){
if(!f2){
f2=1;
cnt=mp[g[i]];
pos2=g[i];
}
else{
if(cnt>mp[g[i]]){
cnt=mp[g[i]];
pos2=g[i];
}
else if(cnt==mp[g[i]]) pos2=min(pos2,g[i]);
}
}
int j=i+1;
while(g[i]==g[j]&&j<=n) j++;
i=j-1;
}
if(f2){
int t=n;
while(cnt--){
ans2[t]=pos2;
t-=m;
}
for(int i=1,j=1;i<=n;i++){
if(g[i]==pos2) continue;
while(ans2[j]&&j<=n) j++;
ans2[j++]=g[i];
}
}
if(f1&&!f2){
for(int i=1;i<=n;i++) cout<<ans1[i]<<' ';
}
else if(!f1&&f2){
for(int i=1;i<=n;i++) cout<<ans2[i]<<' ';
}
else if(f1&&f2){
if(check(ans1,ans2)){
for(int i=1;i<=n;i++) cout<<ans1[i]<<' ';
}
else{
for(int i=1;i<=n;i++) cout<<ans2[i]<<' ';
}
}
else cout<<-1;
cout<<endl;
}
signed main(){
//freopen("in.txt","r",stdin);
//freopen("ans.txt","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}