rt,蒟蒻刚开始尝试写构造,第一个点总是 RE,求调。
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int n,mp[N],a[N],f,have[N],s[N<<1],num;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
// freopen("P9137_1.in","r",stdin);
// freopen("P9137.in","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)mp[i]=2;
for(int i=1;i<=n;i++)cin>>a[i],mp[a[i]]--;
if(n==1){cout<<-1;return 0;}
for(int i=1;i<=n;i++){if(mp[i]==2){f=i;break;}}
if(f==0){
cout<<n+2<<"\n"<<a[n]<<" ";
for(int i=1;i<n;i++)cout<<a[i]<<" ";
cout<<a[1]<<" "<<a[1];
return 0;
}
mp[f]--,have[f]=1,have[a[1]]=1,s[++num]=f,s[++num]=a[1];
cout<<n<<"\n"<<f<<" ";
for(int i=2;i<=n;i++){
if(i==n)cout<<f;
else if(have[a[i]]==1){
cout<<f<<" ",mp[f]--;
while(s[num]!=f)mp[s[num]]++,have[s[num]]=0,num--;
f=a[i];
}
else if(mp[a[i]]==1){
for(int j=1;j<=n;j++){
if(mp[j]==1){
cout<<j<<" ",mp[j]--;
if(have[j]==1)while(s[num]!=j)mp[s[num]]++,have[s[num]]=0,num--;
else have[j]=1,s[++num]=j;
break;
}
}
i++,mp[a[i]]=2,cout<<a[i]<<" ";
}
else{
for(int j=1;j<=n;j++){
if(mp[j]==1){
cout<<j<<" ",mp[j]--;
if(have[j]==1)while(s[num]!=j)mp[s[num]]++,have[s[num]]=0,num--;
else have[j]=1,s[++num]=j;
break;
}
}
s[++num]=a[i],have[a[i]]=1;
}
//cout<<i<<"\n";
}
return 0;
}
/*
对于小J下一张要出的牌,另一张对应的牌有三种情况:
1、另一张牌在小I手中
2、另一张牌在牌堆中
3、另一张牌在小J手中
对于第一种情况,我们可以在下一轮立即把这张牌出出来收走小J出的牌
对于第二种情况,我们需要立即将牌堆中的牌收走,因为另一张在排队中所以牌堆底部的牌的对应牌仍在我们手中
对于第三种情况,我们可收可不收,因为这次出出来并不能让小J产生收牌操作,所以我们大可以等到下一次再出手
*/