HDU 6215 Brute Force Sorting (链表维护数组)

49 篇文章 0 订阅


Brute Force Sorting

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 709    Accepted Submission(s): 176


Problem Description
Beerus needs to sort an array of  N  integers. Algorithms are not Beerus's strength. Destruction is what he excels. He can destroy all unsorted numbers in the array simultaneously. A number  A[i]  of the array is sorted if it satisfies the following requirements.
1.  A[i]  is the first element of the array, or it is no smaller than the left one  A[i1] .
2.  A[i]  is the last element of the array, or it is no bigger than the right one  A[i+1] .
In  [1,4,5,2,3] , for instance, the element  5  and the element  2  would be destoryed by Beerus. The array would become  [1,4,3] . If the new array were still unsorted, Beerus would do it again.
Help Beerus predict the final array.
 

Input
The first line of input contains an integer  T (1T10)  which is the total number of test cases.
For each test case, the first line provides the size of the inital array which would be positive and no bigger than  100000 .
The second line describes the array with  N  positive integers  A[1],A[2],,A[N]  where each integer  A[i]  satisfies  1A[i]100000 .
 

Output
For eact test case output two lines.
The first line contains an integer  M  which is the size of the final array.
The second line contains  M  integers describing the final array.
If the final array is empty,  M  should be  0  and the second line should be an empty line.
 

Sample Input
  
  
5 5 1 2 3 4 5 5 5 4 3 2 1 5 1 2 3 2 1 5 1 3 5 4 2 5 2 4 1 3 5
 

Sample Output
  
  
5 1 2 3 4 5 0 2 1 2 2 1 3 3 2 3 5
 

Source
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:   6216  6215  6214  6213  6212 

题意:


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


思路:


我们可以采用数组模拟一个双向链表,再用一个队列来模拟整个的删除过程.队列中存放的是可能从该点开始产生非排序序列的下标,每次从队列中拿出一个结点,看后面的是否满足排序,不满足就删除这一段然后一直后移,直到整个队列为空.

这里需要注意要将删除结点的上一个结点加入继续判断

总结: 之前总结的这类区间变动问题 一般用并茶几pre数组维护, 现在又学到了 双端链表。。当然是数组模拟的, 链表存的是下标

比赛里用pre数组维护的, 感觉很对 就是wa,自己测得阳历都对, 暴力对拍才发现错了。。是因为用pre数组维护,没有链表的更新,使其依然是一条链,用pre相当于只跑了一遍。。

 suf[pre[que[cur]]] = suf[p];
 pre[suf[p]] = pre[que[cur]];
 que[cnt++] = pre[que[cur]];


#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;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值