『8.20 類比賽』冒泡排序

來源:互聯網
上載者:User

標籤:img   std   gis   之間   cstring   長度   http   stream   很多   

題目描述

給定n,k,和一個長度為n的序列,請輸出這個序列冒泡排序k次之後的結果。

 

解題思路

我們觀察上面給出的虛擬碼,可以發現這是一段把代碼排序成升序的代碼,那我們來考慮一下冒牌排序的幾個特徵。

一個大的數要向右交換,但是一次交換之後就可以換很多位置,所以換一次就不知道跑到哪裡去了,所以很難維護。

一個小的數每次最多和它左邊的更大的數交換一次,所以一次最多向左邊跑一個位置,比大數不知道好維護到那裡去了。

進一步思考,k次交換之後,最多可以向左跑k步,也就是說k+1位置的數最遠能跑到1的位置上來,那我們就可以大膽的猜想了,前k+1個數在第一輪交換之後最小的數會到第一個位置。假如前k+1個中最小的數沒能跑到第一個位置,那說明一定有一個比它小的數會在它的左邊擋它,和我們的假設矛盾,所以猜想成立。

以此類推,第k+2個數最多到第二個位置上,按照我們的結論,第二個位置上的數應該是1 ~ k+2之間除去第一個位置的數以外的最小的數。

接著推下去,我們就完成了所有的數的位置的計算。

可以看出來,我們需要維護一個最小值,顯然可以使用線段樹,也可以使用優先隊列,注意push的時候要用負值。

 

 

代碼
 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int maxn=100050; 8 int n,k; 9 int a[maxn];10 priority_queue<int>q;11 int main(){12     scanf("%d%d",&n,&k);13     for(register int i=1;i<=n;i++)scanf("%d",&a[i]);14     for(register int i=1;i<=min(n,k+1);i++){15         q.push(-a[i]);16     }17     for(register int i=2;i+k<=n;i++){18         printf("%d\n",-q.top());19         q.pop();20         q.push(-a[i+k]);21     }22     while(!q.empty()){23         printf("%d\n",-q.top());24         q.pop();25     }26 }

 

『8.20 類比賽』冒泡排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.