「杂题乱刷2」AT_arc121_c
题目链接
AT_arc121_c [ARC121C] Odd Even Sort
解题思路
首先特判 \(n \le 3\) 的情况,这部分直接模拟即可,略过。
对于 \(n > 3\) 的情况,我们直接把 \(4 \sim n\) 这些数字移到后缀,这里次数是 \(\displaystyle\frac{n \times (n+1)}{2}\) 级别的,直接分讨奇偶即可,考虑如何有效的跳过一次操作,直接找对当前操作的没有影响的可操作的下标最小的数字进行一次多余操作即可。
至于前 \(3\) 个数字,参考 \(n = 3\) 的情况即可。
参考代码
ll n;
ll a[100010];
ll b[100010];
ll pd;
ll A[100010];
vector<ll>ans;
void swp(ll x)
{
swap(a[x],a[x+1]);
swap(b[a[x]],b[a[x+1]]);
ans.pb(x);
}
void sol3(ll l,ll r,ll pd)
{
while(a[l]>a[l+1] || a[l+1]>a[l+2])
{
if(l%2==pd)
swp(l);
else
swp(l+1);
pd^=1;
// forl(i,1,n)
// cout<<a[i]<<' ';
// cout<<endl;
}
}
void print()
{
cout<<ans.size()<<endl;
for(auto i:ans)
cout<<i<<' ';
cout<<endl;
for(auto i:ans)
swap(A[i],A[i+1]);
forl(i,1,n)
if(A[i]!=i)
{
cout<<"Wrong Answer!\n";
return ;
}
}
/*
*/
void _clear(){}
void solve()
{
_clear();
cin>>n;
forl(i,1,n)
cin>>a[i],
A[i]=a[i],
b[a[i]]=i;
if(n==1)
{
cout<<0<<endl;
return ;
}
forl(i,1,n)
{
if(a[i]!=i)
break;
if(a[i]==n)
{
cout<<0<<endl<<endl;
return ;
}
}
ans.clear();
if(n==2)
{
cout<<1<<endl;
cout<<1<<endl;
return ;
}
pd=1;
if(n==3)
{
sol3(1,3,1);
print();
return ;
}
forr(i,n,4)
{
if(b[i]%2==pd)
forl(j,b[i],i-1)
pd^=1,
swp(j);
else
{
if(pd)
{
if(a[1]!=i && a[2]!=i)
swp(1);
else
swp(3);
}
else
{
if(a[2]!=i && a[3]!=i)
swp(2);
else
swp(4);
}
pd^=1;
forl(j,b[i],i-1)
pd^=1,
swp(j);
}
}
sol3(1,3,pd);
print();
}

浙公网安备 33010602011771号