思路参考:寄,大型控分失败现场——Codeforces Round #773 (Div. 1,Div. 2)讲解_哔哩哔哩_bilibili
D. Repetitions Decoding
有一定难度的构造题,考虑逐步“消去”数组中的数,具体思路见视频。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
int t, n, a[505], cnt;
map<int,int> mp;
vector<P> ans1;
vector<int> ans2;
inline void init(){
ans1.clear(); ans2.clear();
cnt=0; mp.clear();
}
inline void solve(){
int now = 0; // a[now]==a[1]
for(int i=2; i<=n; i++)
if(a[i]==a[1]) {now=i; break;}
for(int j=2; j<=now-1; j++) // 按顺序复制(1,now)部分的所有字符
ans1.push_back({cnt+now+j-2,a[j]});
ans2.push_back(2*(now-1)); //本次构造出的平方串长度
cnt += 2*(now-1); //后面要删去这一段平方串,需要累加删掉的长度
reverse(a+1,a+now+1); //把[a+1,a+now+1)部分反转
for(int i=2; i<=n; i++){ //模拟删掉已经构造好的平方串
if(i<now) a[i-1]=a[i];
if(i>now) a[i-2]=a[i];
}
n-=2; //别忘了减去a[1]和a[now]的长度2
}
int main(){
// freopen("input.txt","r",stdin);
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin>>t; while(t--){
init();
cin>>n; for(int i=1; i<=n; i++) cin>>a[i], mp[a[i]]++;
bool ok = 1;
for(auto&P:mp) if(P.second%2) {ok=0; break;}
if(!ok) {cout<<-1<<'\n'; continue;}
int tmpn=n; //solve过程中,n会减小,所以要用一个tmpn记录初始长度
for(int i=1; i<=tmpn/2; i++) solve(); //构造需要进行n/2次
cout<<ans1.size()<<'\n';
for(auto&P:ans1) cout<<P.first<<' '<<P.second<<'\n';
cout<<ans2.size()<<'\n';
for(int&x:ans2) cout<<x<<' ';
cout<<'\n';
}
}