P13 2021蓝桥杯省B(C++)T9 双向排序

牢久没写题解了(其实是大一基本没怎么碰过算法,就偶尔打一次AT)

这个暑假没事干,想着可以刷刷蓝桥杯。但是自己实力一坨,所以就决定从C++省B开刷,于是就碰到了这题。

当时看了半天也没感觉,于是在纸上比划比划发现,其实这题最大值只会出现在两端,这是显然因为无论操作多少次(>0),最后数组都是先降再增。因此就很简单了,只需要从大到小逐个确定每个数在两端的哪一端即可,然后设置两个变量 \(head\)\(end\),来表示两端下标。

注意到对于某个数 \(i\),如果坐标等于它(\(end\))或者比它大的位置出现了操作 \(0\),它就会跑到左端;反之等于或比它(\(head\))小就出现在右端。所以直接开个数组记录,并且每一次推进两端的时候合并一下就好了。

不知道为什么看了半天题解区没这种简单做法...我真帅吧(其实这题感觉就个绿顶天了)

const int N=100010;

int v[N][2];
int n,m,op[N],q[N],ans[N];

signed main(){
  IOS
  cin>>n>>m;
  for(int i=1;i<=m;++i){
    cin>>op[i]>>q[i];
    v[q[i]][op[i]]=i;
  }
  int head=1,end=n;
  for(int i=n;i;--i){
    v[head][1]=max(v[head][1],v[head-1][1]);
    v[end][0]=max(v[end][0],v[end+1][0]);
    if(!v[end][0]){ ans[end--]=i; continue;} //前降,后升
    if(v[end][0]>v[head][1])
      ans[head++]=i;
    else ans[end--]=i;
  }

  for(int i=1;i<=n;++i) cout<<ans[i]<<' ';
  return 0;
}

· EOF

posted @ 2025-07-16 10:37  ComplexityMFC  阅读(6)  评论(0)    收藏  举报