HDU 6215 Brute Force Sorting 模拟双端链表

一层一层删 

链表模拟

最开始写的是一个一个删的 WA

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que;
const double EPS = 1.0e-8;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
const int  maxn = 1e5 + 100;
const int  maxm = 300;
int a[maxn];
int pre[maxn], last[maxn];
int visit[maxn];
queue<int> que;
int main()
{
        int t ;
        cin >> t;
        while (t--)
        {
                mem(visit, 1);
                pre[0] = -1, last[0] = 1;
                int n;
                cin >> n;
                a[0] = -1;
                a[n + 1] = INT_MAX;
                for (int i = 1; i <= n; i++)
                {
                        scanf("%d", &a[i]);
                        pre[i] = i - 1, last[i] = i + 1;
                }
                int flag = 0;
                for (int i = 1; i < n; i++)
                        if (a[i] <= a[i + 1])
                        {
                                flag = 1;
                        }
                if (!flag)
                {
                        cout << 0 << endl;
                        continue;
                }
                for (int i = 1; i <= n; i++)
                {
                        if (a[pre[i]] > a[i] || a[last[i]] < a[i])
                        {
                                que.push(pre[i]);
                                visit[i] = 0;
                                pre[last[i]] = pre[i];
                                last[pre[i]] = last[i];
                        }
                }
                while (!que.empty())
                {
                        int now = que.front();
                        que.pop();
                        if (!visit[now])
                        {
                                continue;
                        }
                        if (a[pre[now]] > a[now] || a[last[now]] < a[now])
                        {
                                que.push(pre[now]);
                                visit[now] = 0;
                                pre[last[now]] = pre[now];
                                last[pre[now]] = last[now];
                        }
                }
                int sum = 0;
                for (int i = 1; i <= n; i++)
                        if (visit[i])
                        {
                                sum++;
                        }
                cout << sum << endl;
                if (sum)
                {
                        for (int i = 1; i <= n; i++)
                                if (visit[i])
                                {
                                        printf("%d ", a[i]);
                                }
                        cout << endl;
                }
        }
}
View Code

正解:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + 7;
int que[maxn], a[maxn], pre[maxn], suf[maxn], n, top;
int main()
{
    int _;
    cin >> _;
    while(_--)
    {
        top = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
        {
            pre[i] = i-1;
            suf[i] = i+1;
            scanf("%d", &a[i]);
            que[top++] = i;
        }
        suf[0] = 1;
        int ans = n, flag = 0;
        while(1)  //一轮一轮的删, 如果没有改动过,说明都是有序的了
        {
            int cnt = 0, cur = 0, flag = 0;
            while(cur < top)  //当前这一轮
            {
                int p = que[cur], num = 0;
                while(suf[p] <= n && a[p] > a[suf[p]])  //把一个连续的删掉
                {
                    flag = 1;
                    num++;
                    p = suf[p];
                }
                if(num)
                {
                    ans -= num+1;
                    suf[pre[que[cur]]] = suf[p];  //维护链表,使其联通
                    pre[suf[p]] = pre[que[cur]];
                    que[cnt++] = pre[que[cur]];
                }
                while(que[cur] <= p && cur < top)  //修改当前指针
                    cur++;
            }
            top = cnt;
            if(!flag) break;  //没有就跳出
        }
        printf("%d\n", ans);
        int cur = 0;
        while(cur <= n)
        {
            if(cur)
                printf("%d ",a[cur]);
            cur = suf[cur];
        }
        puts("");
    }
    return 0;
}

 

posted @ 2017-09-19 00:11  Aragaki  阅读(298)  评论(0编辑  收藏  举报