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

浙公网安备 33010602011771号