思路参考:寄,大型控分失败现场——Codeforces Round #773 (Div. 1,Div. 2)讲解_哔哩哔哩_bilibili
有一定难度的构造题,考虑逐步“消去”数组中的数,具体思路见视频。
#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'; } }