1. 程式人生 > >$[ USACO 2018 OPEN ] Out of Sorts (Silver)$

$[ USACO 2018 OPEN ] Out of Sorts (Silver)$

順序 lse ans c++ 一位 -i 最大 列排序 gis


\(\\\)

\(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;   
}

$[\ USACO\ 2018\ OPEN\ ]\ Out\ of\ Sorts\ (Silver)$