[ USACO 2018 OPEN ] Out of Sorts (Silver)

\(\\\)

\(Description\)


运行以下代码对一长为\(N\)的数列\(A\)排序,不保证数列元素互异:

cnt = 0
sorted = false
while (not sorted):
   cnt = cnt + 1
   sorted = true
   for i = 0 to N-2:
      if A[i+1] < A[i]:
         swap A[i], A[i+1]
         sorted = false

求退出循环后\(cnt\)的值。

  • \(N\in [0,10^5]\)\(A_i\in [0,10^9]\)

\(\\\)

\(Solution\)


  • 其实就是正常的顺序冒泡排序,注意到在一次循环中,一个很大的数是会连续向后移动多次的,而小一点的数只会左移一位,因此我们只需统计出每一个数需要左移的次数取最大值就是答案。
  • 于是做法是记录下标后将数列排序,但是注意\(sort\)是不稳定的,因此需要双关键字,即相同的数字按照在原数列中的出现次序排序。

\(\\\)

\(Code\)


#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100010
#define R register
#define gc getchar
using namespace std;

inline int rd(){
    int x=0; bool f=0; char c=gc();
    while(!isdigit(c)){if(c=='-')f=1;c=gc();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return f?-x:x;
}

int n,ans;
struct num{int x,p;}s[N];

inline bool cmp(num x,num y){return x.x==y.x?x.p<y.p:x.x<y.x;}

int main(){
    n=rd();
    for(R int i=1,x;i<=n;++i){s[i].x=rd();s[i].p=i;}
    sort(s+1,s+1+n,cmp);
    for(R int i=1;i<=n;++i) ans=max(ans,s[i].p-i+1);
    printf("%d\n",ans);
    return 0;	
}
posted @ 2018-09-17 10:51  SGCollin  阅读(251)  评论(0编辑  收藏  举报