HDU 6215 2017Brute Force Sorting 青岛网络赛 队列加链表模拟

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6215

题意:给你长度为n的数组,定义已经排列过的串为:相邻两项a[i],a[i+1],满足a[i]<=a[i+1]。我们每次对当前数组删除非排序过的串,合并剩下的串,继续删,直到排序完成。

解法:双向链表模拟过程,设置一个队列,用于存可能产生非排序过的串的头结点,每次从队列中拿出一个头结点判断后面的情况,若还能继续删除,则将头结点的上一个结点放入队列继续判,知道没有别的结点为止。

 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int a[maxn], Next[maxn], Last[maxn];
int que[maxn], top;

int main()
{
    int T, n;
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        a[0] = 0;
        Next[0] = 1;
        Last[n+1] = n;
        int ans = n;
        for(int i=1; i<=n; i++){
            Next[i] = i+1;
            Last[i] = i-1;
            scanf("%d", &a[i]);
            que[top++] = i;
        }
        int flag = 1;
        while(flag)
        {
            flag = 0;
            int s = 0;
            int now = 0;
            while(now < top){
                int item = que[now];
                int len = 0;
                while(Next[item]<=n){
                    if(a[item] > a[Next[item]]){
                        len++;
                        flag = 1;
                        item = Next[item];
                    }
                    else break;
                }
                if(len) ans = ans - len - 1;
                if(len){
                    Next[Last[que[now]]] = Next[item];
                    Last[Next[item]] = Last[que[now]];
                    que[s++] = Last[que[now]];
                }
                while(now < top && que[now] <= item) now++;
            }
            top = s;
        }
        printf("%d\n", ans);
        int now = 0;
        while(now <= n){
            if(now != 0) printf("%d ", a[now]);
            now = Next[now];
        }
        printf("\n");
    }
    return 0;
}

 

posted @ 2017-09-19 14:16  zxycoder  阅读(361)  评论(0编辑  收藏  举报