HDU 6215 Brute Force Sorting 模拟

来源:互联网 发布:小米网络电视安装 编辑:程序博客网 时间:2024/06/05 01:49

题目链接:HDU 6215

Brute Force Sorting

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


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
551 2 3 4 555 4 3 2 151 2 3 2 151 3 5 4 252 4 1 3 5
 

Sample Output
51 2 3 4 5 021 2 21 3 32 3 5
 

Source
2017 ACM/ICPC Asia Regional Qingdao Online 
 

题意:给出一个序列,每次进行一种操作,从左到右扫一遍,然后每个数如果比左面相邻的小或者比右边相邻的大,就删掉,不更新,扫过一遍统一更新,问最后序列元素。

题目分析:之前扫过没有修改过的位置之后肯定也不会修改,换句话说第i次修改在a1,a2,a3,,,位置上删除了元素,那么第i+1次修改也一定在a1,a2,a3,,,位置的左边或者右边,我们只需要维护一个修改的队列,按照队列一个一个修改,再入队列,一遍修改完统一更新下链表的指针关系,然后进行下一轮即可。

注意有以下几个需要注意,首先在一遍扫描前要预处理出每个修改的位置的前驱后继,然后每次删除节点就可以直接更新了。连续的一堆节点删除时显然只统计最开始的。ai被删除时入队列的有它的前驱和后继,前驱好入队列,后继不好统计,所以在一遍扫描完后再把队列里的所有节点的后继入队列。但是我们操作必须严格递增操作,所以暴力排序一下,,,最后直接scanf会超时,加上超级快读,瞬间150+ms。

PS:写这题各种烦,,这么繁琐的题大家过的都好快呀,,果然是姿势不对吗

#include <iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<queue>using namespace std;int s[111111],nexts[111111],pre[111111];int ps[111111];int mark[111111];int q[522222];int marks[111111];namespace fastIO {#define BUF_SIZE 1000000    //fread -> read    bool IOerror = 0;    inline char nc() {        static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;        if(p1 == pend) {            p1 = buf;            pend = buf + fread(buf, 1, BUF_SIZE, stdin);            if(pend == p1) {                IOerror = 1;                return -1;            }        }        return *p1++;    }    inline bool blank(char ch) {        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';    }    inline void read(int &x) {        char ch;        while(blank(ch = nc()));        if(IOerror)            return;        for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');    }#undef BUF_SIZE};using namespace fastIO;int main(){    int T,n;    int num=0;    read(T);    while(T--)    {        read(n);        num=0;        memset(s,0,sizeof(s));        memset(pre,0,sizeof(pre));        memset(mark,0,sizeof(mark));        memset(marks,0,sizeof(marks));        memset(nexts,0,sizeof(nexts));        for(int i=0;i<n;i++)        {            read(s[i]);            nexts[i]=i+1;            pre[i]=i-1;        }        int left=0,right=0;        for(int i=0;i<n;i++)        {            ps[i]=pre[i];        }        for(int i=0;i<n;i++)        {            if(ps[i]!=-1)            {                int p=ps[i];                if(s[p]>s[i])                {                        mark[i]=1;                        num++;                    nexts[pre[i]]=nexts[i];                    pre[nexts[i]]=pre[i];                    if(p==pre[i])                    {                        marks[p]=1;                        q[right++]=p;                    }                    continue;                }            }            if(nexts[i]!=n)            {                int ns=nexts[i];                if(s[ns]<s[i])                {                        mark[i]=1;                        num++;                    nexts[pre[i]]=nexts[i];                    pre[nexts[i]]=pre[i];                    if(ps[i]==pre[i]&&ps[i]!=-1)                    {                        marks[ps[i]]=1;                        q[right++]=ps[i];                    }                    continue;                }            }        }        int tot=n;        while(left<right)        {            int pos=q[left++];                        if(tot>pos)            {                int rt=right;                for(int i=left-1;i<rt;i++)                {                    if(nexts[q[i]]==n) continue;                    q[right++]=nexts[q[i]];                }                sort(q+left,q+right);                for(int i=left-1;i<right;i++)                {                    ps[q[i]]=pre[q[i]];                }            }            tot=pos;            int i=pos;            int j=nexts[pos];            if(ps[i]!=-1)            {                int p=ps[i];                if(s[p]>s[i])                {                    if(mark[i]==0)                    {                        mark[i]=1;                        num++;                    }                    nexts[pre[i]]=nexts[i];                    pre[nexts[i]]=pre[i];                    if(p==pre[i])                    {                        q[right++]=p;                    }                    continue;                }            }            if(nexts[i]!=n)            {                int ns=nexts[i];                if(s[ns]<s[i])                {                        mark[i]=1;                        num++;                    nexts[pre[i]]=nexts[i];                    pre[nexts[i]]=pre[i];                    if(ps[i]==pre[i]&&ps[i]!=-1)                    {                        q[right++]=ps[i];                    }                    continue;                }            }        }        printf("%d\n",n-num);        for(int i=0;i<n;i++)        {            if(mark[i]==0)            {                printf("%d ",s[i]);            }        }        printf("\n");    }}


原创粉丝点击