hdu 6215 Brute Force Sorting 【链表+队列】



题意:


         给你一个数列,每次删除所有a[i]. a[i]满足, a[i]<=a[i-1] || a[i]>=a[i+1], 

         从而获得一个新数列,如果新数列还有这样的数,重复以上操作。

        直到数列成为单调递增为止。


题解:


        很容易想到链表模拟,但是直接一遍一遍扫肯定tle

        然后可以发现,每次删掉一个数之后,受影响的只有他之前和他之后的两个数。

        所以,我们可以用两个队列,一个保存当前剩余的数有哪些,另一个保存,上次删除的数的上一个数是那些:



#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
const int eps=1e-4;
int n,x,cnt;
int pre[maxn],nxt[maxn],num[maxn],ans[maxn];
queue<int>que,tque;
void init(){
    cnt=0;
    while(!que.empty()) que.pop();
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d",&x);
        num[++cnt]=x;
        pre[cnt]=cnt-1;
        nxt[cnt]=cnt+1;
        que.push(i);
    }
    num[0]=0;nxt[0]=1;
    num[++cnt]=maxn;
    pre[cnt]=cnt-1;
    nxt[cnt]=cnt+1;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        init();
        while(1){
            int t,y,z,f;
            while(!tque.empty()) tque.pop();
            while(!que.empty()){
                t=que.front();
                que.pop();
                y=nxt[t];
                z=num[t];
                f=0;
                while(y!=cnt&&z>num[y]){
                    z=num[y];
                    y=nxt[y];
                    f=1;
                }
                if(f){
                    pre[y]=pre[t];
                    nxt[pre[t]]=y;
                    tque.push(pre[t]);
                    while(!que.empty()&&que.front()<y)
                        que.pop();
                }
            }
            if(tque.size()==0) break;
            while(!tque.empty()){
                que.push(tque.front());
                tque.pop();
            }
        }
        int s=0,p=0;
        while(s!=cnt){
            if(s!=0)
                ans[++p]=num[s];
            s=nxt[s];
        }
        printf("%d\n",p);
        for(int i=1;i<=p;++i)
            printf("%d ",ans[i]);
        puts("");
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值