Brute Force Sorting (数组实现双向链表 经典模版)ACM-ICPC 青岛站

Beerus needs to sort an array of  NN 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]A[i] of the array is sorted if it satisfies the following requirements. 
1.  A[i]A[i] is the first element of the array, or it is no smaller than the left one  A[i1]A[i−1]
2.  A[i]A[i] is the last element of the array, or it is no bigger than the right one  A[i+1]A[i+1]
In  [1,4,5,2,3][1,4,5,2,3], for instance, the element  55 and the element  22 would be destoryed by Beerus. The array would become  [1,4,3][1,4,3]. If the new array were still unsorted, Beerus would do it again. 
Help Beerus predict the final array.
InputThe first line of input contains an integer  T (1T10)T (1≤T≤10) 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  100000100000
The second line describes the array with  NN positive integers  A[1],A[2],,A[N]A[1],A[2],⋯,A[N] where each integer  A[i]A[i]satisfies  1A[i]1000001≤A[i]≤100000.OutputFor eact test case output two lines. 
The first line contains an integer  MM which is the size of the final array. 
The second line contains  MM integers describing the final array. 
If the final array is empty,  MM should be  00 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 

题目大意:给出一串无序的数字序列,不断执行“摧毁”操作,直到摧毁数字个数为0,该操作定义为:若满足A[i]<A[i-1] 或者 A[i]>A[i+1]中任意条件,则删除该元素。输出最终序列。

解题思路:显然,每次暴力扫数组直到摧毁个数为0时间复杂度为O(n^2),导致TLE

因为每个元素改动后,受影响的只有它的前一个元素和后一个元素,因此可以用数组记录上一次更改过的节点的左节点。利用数组模拟双向链表,方便删除操作。

每次循环,打开上一次的记忆,逐个判断是否异常,如果异常,就把该节点自身和受牵连的另一节点做删除操作,然后将其左节点录入记忆数组。重复上述操作,直到记忆数组规模为0

Code:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <climits>
#include <vector>
using namespace  std;
const int maxn=1e6+5;
int now,pre;
int value[maxn],Left[maxn],Right[maxn],vis[maxn];
vector<int > temp;
set<int > cnt;
int main(){
    int t,n;
    cin>>t;
    while(t--){
        memset(vis, 0, sizeof(vis));
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%d",&value[i]);
            Left[i]=i-1;
            Right[i]=i+1;
            cnt.insert(i);
        }
        Right[0]=1; Left[n+1]=n;
        value[0]=0;value[n+1]=INT_MAX;
        
        while(cnt.size()){
            temp.clear();
            for(int x:cnt){
                int Lx=Left[x],Rx=Right[x];
                if(value[Lx]>value[x]){
                    temp.push_back(x);
                    temp.push_back(Lx);
                }
                if(value[Rx]<value[x]){
                    temp.push_back(x);
                    temp.push_back(Rx);
                }
            }
            cnt.clear();
            for(int x:temp){
                if(!vis[x]){
                    int Lx=Left[x],Rx=Right[x];
                    Left[Rx]=Lx;Right[Lx]=Rx;
                    cnt.insert(Lx);
                    vis[x]=1;
                }
            }
            
        }
        int k=0;
        
        for(int i=Right[0];i!=n+1;i=Right[i]) k++;
        cout<<k<<endl;
        for(int i=Right[0];i!=n+1;i=Right[i]) printf("%d ",value[i]);
        printf("\n");
        
        
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39665840/article/details/79833446