hdu6215 双向链表,模拟

hdu6215

题意:给出一个序列。如果不满足 a[i-1]<=a[i]<=a[i+1],则称数 a[i] 是无序的。 现在每一次把序列中所有无序的数删去,剩下的数合成新的序列,直到无法删除为止。 输出最后剩下的序列。

tags:就是模拟。。

把所有连续的无序的数的第一个加入队列,然后用双向链表记录下标,不断删除即可。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 200005;

struct P { int val, next, pre; } p[N];
int n;
bool vis[N];
queue<int > q;    int Q[N], tail;
int main()
{
    int T;  scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        mes(vis, false);
        vis[0]=vis[n+1]=true;
        p[0].val=0, p[n+1].val=INF;
        while(!q.empty()) q.pop();
        rep(i,1,n)
        {
            scanf("%d", &p[i].val);
            p[i].next=i+1, p[i].pre=i-1;
        }
        rep(i,1,n)
            if(p[i-1].val<=p[i].val && p[i].val>p[i+1].val)
                q.push(i), Q[++tail]=i;
        int ans=n;
        while(!q.empty())
        {
            int u=q.front(), i;
            q.pop();
            if(vis[u] || p[u].val<=p[p[u].next].val) continue;
            vis[u]=true;     --ans;
            for(i=p[u].next; i<=n; i=p[i].next)
            {
                if(p[p[i].pre].val<=p[i].val) break;
                vis[i]=true;    --ans;
            }
            p[p[u].pre].next=i;   p[i].pre=p[u].pre;
            q.push(p[u].pre);  q.push(i);
        }
        printf("%d
", ans);
        rep(i,1,n) if(!vis[i])
            printf("%d ", p[i].val);
        puts("");
    }

    return 0;
}
原文地址:https://www.cnblogs.com/sbfhy/p/7576974.html