Jzoj3542 氣泡排序

2022-05-09 15:05:46 字數 1428 閱讀 3946

下面是一段實現氣泡排序演算法的c++**:

for (int i=1;i<=n;i++)

for (int j=1;j<=n-i;j++)

if (a[j]>a[j+1]) swap(a[j],a[j+1]);

其中待排序的a陣列是乙個1~n的排列,swap函式將交換陣列中對應位置的值。

對於給定的陣列a以及給定的非負整數k,使用這段**執行了正好k次swap操作之後陣列a中元素的值會是什麼樣的呢?

是乙個模擬題也~

我們先來考慮乙個數的移動情況

假設x前面有t[x]個數比x要大,那麼顯然在i<=t[x]的時候,x每次都會被前移一位,之後就不會再向前了

又因為,前移的次數=swap的次數,所以我們可以先求出t陣列,讓後二分i,使得swap的次數不超過k

設列舉出來的這個i的上界為m,那麼所有t[x]>=m的數必然前移了m位,讓後我們將所有t[x]

最後由於沒到k次,差的部分直接用模擬補上

#pragma gcc opitmize("o3")

#pragma g++ opitmize("o3")

#include

#include

#include

using

namespace

std;

int n,v[1000010],t[1000010],b[1000010]; long

long k;

struct fenwick

inline

void add(int x,int v=1)

inline

long

long sum(int x)

} r,c;

int main()

r.clear();

for(int i=1;i<=n;++i) r.add(t[i]+1),c.add(t[i]+1,t[i]);

int l=0,r=n;

for(int m;l1>>1;

if(k>=c.sum(m+1)+m*(n-r.sum(m+1))) l=m;

else r=m-1;

} k-=c.sum(l+1)+l*(n-r.sum(l+1));

for(int i=1;i<=n;v[i++]=0)

if(t[i]>=l)v[i-l]=v[i]; else b[++*b]=v[i];

sort(b+1,b+1+*b);

for(int i=n;i;--i) if(!v[i]) v[i]=b[(*b)--];

for(int j=1;jif(v[j]>v[j+1]) swap(v[j],v[j+1]),--k;

if(k) puts("impossible!"); else

for(int j=1;j<=n;++j) printf("%d ",v[j]);

}

JZOJ3542氣泡排序

下面是一段實現氣泡排序演算法的c for int i 1 i n 1 i for int j 1 j n i j if a j a j 1 swap a j a j 1 其中待排序的a陣列是乙個1 n的排列,swap函式將交換陣列中對應位置的值。對於給定的陣列a以及給定的非負整數k,使用這段 執行了...

jzoj5931 氣泡排序

氣泡排序的交換次數被定義為交換過程的執行次數。小 s 開始專注於研究 度為 n 的排列,他想知道,在你運氣足夠好的情況下 即每次氣泡排序的交換次數都是可能的最少交換次數,彷彿有上帝之手在操控 對於乙個等概率隨機的長度為n 的排列,進行這樣的氣泡排序的期望交換次數是多少?ion的梗玩到現在真是 一開始...

氣泡排序 排序 氣泡排序

既然寫了計組思來想去便打算把資料結構也寫下來,寫的時候總是發現看的時候無法發現的問題,受益良多。交換排序的基本思想 exchange until sorted 順序,分支,迴圈 注意偽 的熟悉 下面介紹兩種交換演算法 首先進行聯想,用乙個圖進行輔助聯想 水冒泡過程 頂部是陣列的begin,底部理解為...