HDU 6215 Brute Force Sorting(模拟链表 思维)

本文介绍了一个特殊的排序问题,即通过不断删除不符合排序条件的元素来最终得到一个有序数组的方法。文章详细解释了问题背景及要求,并提供了一种高效的解决方案,采用链表模拟的方式实现了O(N)的时间复杂度。

Brute Force Sorting

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

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
【题意】给你一个序列,每次扫一遍序列,同时删除不符合排序标准的数。如果一个数符合标准,则它大于等于左边的数,小于等于右边的数,删完之后右边的数依次填补空位,求删完之后剩下的序列。
【分析】假设我们已经知道了上一次删除的数的位置,那么这一次我们要删的数肯定是上一次删除的数的前驱后缀中选,那么依次模拟链表删下去就好了,复杂度O(N).
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1e5+5;;
const int M = 17;
const int mod = 1e9+7;
const int mo=123;
const double pi= acos(-1.0);
typedef pair<int,int>pii;
int n;
int a[N],pre[N],suf[N],pos[N],poss[N];
bool del[N];
int main() {
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        pre[0]=0;suf[n]=n;
        int cnt=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            pre[i]=i-1;
            suf[i]=i+1;
            del[i]=false;
        }
        a[0]=-1;a[n+1]=N;
        for(int i=1;i<=n;i++){
            if(a[i]>=a[i-1]&&a[i]<=a[i+1])continue;
            pos[++cnt]=i;
            del[i]=true;
            int x=suf[i],y=pre[i];
            pre[x]=y;
            suf[y]=x;
        }
        while(cnt){
            int _cnt=0;
            for(int i=1;i<=cnt;i++){
                int l=pre[pos[i]];
                int r=suf[l];
                if(a[r]<a[l]){
                    if(!del[l]){
                        poss[++_cnt]=l;
                        del[l]=true;
                        int x=suf[l],y=pre[l];
                        pre[x]=y;suf[y]=suf[x];
                    }
                    if(!del[r]){
                        poss[++_cnt]=r;
                        del[r]=true;
                        int x=suf[r],y=pre[r];
                        pre[x]=y;suf[y]=x;
                    }
                }
            }
            cnt=_cnt;
            for(int i=cnt;i>=1;i--){
                pos[i]=poss[i];
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++)if(!del[i])ans++;
        printf("%d\n",ans);
        for(int i=1;i<=n;i++)if(!del[i])printf("%d ",a[i]);
        printf("\n");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/jianrenfang/p/7551695.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值