CF1561E - Bottom-Tier Reversals——有趣的构造题

看题解才做出来,整理一下。

第一步

由于只能翻转奇数前缀,所以对于所有数翻转前后下标奇偶性不变
通过此,判断如果 i 的奇偶性异于 ai 的奇偶性,则无解。

第二步

由于只能翻转 ai 为奇数的前缀,所以猜想相邻的两个数一起考虑,即:先处理 1,2,让它们处理完后变成 xxxx,2,1;再处理 3,4,……;再处理 2i1,2i,让它们处理完后变成 xxxx,2i,2i-1,2i-2,2i-3,...,2,1;最后处理 n2,n1,那么已经不需要处理 n 了,最后排成 n,n-1,...,2,1,只需再用一次翻转操作翻转整个数列。
通过此,猜想每一步至多翻 5 次,因为 5n2+15n2,6 就不行了。

第三步(翻转策略)

假如现在是这么一个状态
xxx,2i-1,xxx,2i,xxx,2i-2,...,2,1
为了叙述方便,记 p1,p22i1,2i 的位置。

  1. 翻转 [1,p1]2i-1,xxx,2i,xxx,2i-2,...,2,1
  2. 翻转 [1,p21]xxx,2i-1,2i,xxx,2i-2,...,2,1
  3. 翻转 [1,p2+1]x,2i,2i-1,xxx,2i-2,...,2,1
    这里做一解释,由于 2i 此时坐标为偶,所以翻的是 p2+1,由于 2i2 的坐标也是偶的,所以 2i2i2 之间肯定有一个 x(代表不相干数),因此不会影响到 2i2 那一块。
  4. 翻转 [1,3]2i-1,2i,x,xxx,2i-2,...,2,1
  5. 最后,翻转 [1,pos(2i2)1](pos 代指数值的位置):xxx,2i,2i-1,2i-2,...,2,1

共 5 次。
可以自己思考一下 xxx,2i,xxx,2i-1,xxx,2i-2,...,2,1 的情况,操作序列是不变的,但注意 p1,p2 在每一次翻转之后是可能发生变化的

代码

点击查看代码
复制
#include <bits/stdc++.h>
using namespace std;
const int N=2025;
int n,a[N],pos[N];
void rev(int m){
printf("%d ",m);
for(int i=1;i<=m/2;i++)swap(a[i],a[m-i+1]);
for(int i=1;i<=m;i++)pos[a[i]]=i;
}
void solve(){
cin>>n;
bool noans=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]&1^i&1)noans=1;
pos[a[i]]=i;
}
if(noans){puts("-1");return;}
cout<<n/2*5+1<<'\n';
pos[0]=n+1;
for(int i=1;i<n;i+=2){
rev(pos[i]),rev(pos[i+1]-1),rev(pos[i+1]+1),rev(3),rev(pos[i-1]-1);
}
printf("%d\n",n);
}
int main(){
int t;cin>>t;while(t--)solve();
}
想想看,这个为什么错了
#include <bits/stdc++.h>
using namespace std;
const int N=2025;
int n,a[N],pos[N];
void rev(int m){
for(int i=1;i<=m/2;i++)swap(a[i],a[m-i+1]);
for(int i=1;i<=m;i++)pos[a[i]]=i;
}
void solve(){
cin>>n;
bool noans=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]&1^i&1)noans=1;
pos[a[i]]=i;
}
if(noans){puts("-1");return;}
cout<<n/2*5+1<<'\n';
pos[0]=n+1;
for(int i=1;i<n;i+=2){
printf("%d %d %d %d %d ",pos[i],pos[i+1]-1,pos[i+1]+1,3,pos[i-1]-1);
rev(pos[i]),rev(pos[i+1]-1),rev(pos[i+1]+1),rev(3),rev(pos[i-1]-1);
}
printf("%d\n",n);
}
int main(){
int t;cin>>t;while(t--)solve();
}
posted @   pengyule  阅读(37)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示