Brute Force Sorting HDU - 6215(模拟双向链表)

本文深入探讨了BruteForceSorting算法,一种通过反复删除未排序元素直至完全排序的策略。文章详细解释了算法的工作原理,包括如何识别并移除不满足排序条件的元素,以及如何迭代处理直至数组完全有序。通过实例演示了算法的具体应用,同时提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Brute Force Sorting HDU - 6215

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[i−1].
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 (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 100000.
The second line describes the array with N positive integers A[1],A[2],⋯,A[N] where each integer A[i] satisfies 1≤A[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 
题意:

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

分析:

因为每次删除一个位置的数字之后,只会影响这个位置的前一个和后一个位置的数之间的关系,所以我们每次把不符合的位置加入到一个vector中,每次遍历vector删除的时候,将要删除的位置两边的位置加入到set中,然后遍历set去找新的不符合条件的数,直到找完或原链为空为止。

code:

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 100100;

struct Node{
    int pos,id;
    Node *pre,*nxt;
}node[N];

vector<int> vec;
set<int> st;
int vis[N];

void Delete(int u){
    Node *p = node[u].pre;
    p->nxt = node[u].nxt;
    node[u].nxt->pre = p;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(vis,0,sizeof(vis));
        memset(node,0,sizeof(node));
        vec.clear();
        st.clear();

        int n,p;
        scanf("%d",&n);

        node[0].pos = 0;
        node[0].id = 0;
        node[0].nxt = &node[1];
        node[0].pre = NULL;

        for(int i = 1; i <= n; i++){
            scanf("%d",&node[i].pos);
            node[i].id = i;
            node[i].nxt = &node[i+1];
            node[i].pre = &node[i-1];
        }

        node[n+1].pos = INF;
        node[n+1].id = n + 1;
        node[n+1].pre = &node[n];
        node[n+1].nxt = NULL;

        vis[0] = vis[n+1] = 1;

        for(int i = 1; i <= n; i++){
            if(node[i].pos < node[i-1].pos || node[i].pos > node[i+1].pos){
                vec.push_back(i);
                vis[i] = 1;
            }
        }

        int flag = 1;
        while(flag){
            st.clear();
            for(int i = 0; i < vec.size(); i++){
                int id1 = node[vec[i]].pre->id;
                int id2 = node[vec[i]].nxt->id;
                if(!vis[id1]) st.insert(id1);
                if(!vis[id2]) st.insert(id2);
                Delete(vec[i]);
            }

            vec.clear();
            for(set<int>::iterator it = st.begin(); it != st.end(); it++){
                int p = *it;
                if(node[p].pos < node[p].pre->pos || node[p].pos > node[p].nxt->pos){
                    vis[p] = 1;
                    vec.push_back(p);
                }
            }

            if(vec.size() == 0) flag = 0;

        }
        for(int i = 1; i <= n; i++){
            if(!vis[i]) vec.push_back(node[i].pos);
        }

        if(vec.size() == 0)
            printf("0\n\n");
        else{
            printf("%d\n",vec.size());
            for(int i = 0; i < vec.size(); i++){
                printf("%d ",vec[i]);
            }
            printf("\n");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值