下面是一段實現氣泡排序演算法的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,底部理解為...