下面是一段實現氣泡排序演算法的c++**:
for (int i=1;ia[j+1])
swap(a[j],a[j+1]);
其中待排序的a陣列是乙個1~n的排列,swap函式將交換陣列中對應位置的值。
對於給定的陣列a以及給定的非負整數k,使用這段**執行了正好k次swap操作之後陣列a中元素的值會是什麼樣的呢?
輸入檔案共2行。
第1行包含空格隔開的乙個正整數n和乙個非負整數k;
第2行包含n個空格隔開的互不相同的正整數,表示初始時a陣列中的排列。
輸出檔案共1行。
若在執行完整個**之後執行swap的次數仍不夠k,那麼輸出乙個字串」impossible!」(不含引號),否則按順序輸出執行swap操作k次之後陣列a的每乙個元素,用空格隔開。
1 11impossible!
n<=10^6
k<=10^12
據說是清華集訓的題。。?【霧】
我們用upper[i]記錄給定陣列中i前面比i大的數的個數。然後二分外層迴圈做了幾次。若做了x次。則總次數=sigma(min(upper[i],x))
然後我們發現,upper[i]<=x的話,那這個數一定排序完畢了。而對於upper[i]>x的部分,他們相對於原數列的位置不變。這樣就可以求出做了x次外層迴圈後的結果了。
然後我們再模擬剩下的一次內層迴圈就可以了。
【果然我還是太弱。。。感謝ydc大大otl】
#include#includeusing namespace std;
int a[1000001],upper[1000001];
int ans[1000001],sa[1000001];
int tr[1000001];
int n;
inline int lowbit(int x)
inline void add(int x,int xx)
inline int sum(int x)
int main()
int l=1,r=n;
long long sx;
while(l<=r)
sx=0;
for(i=1;i<=n;i++)
sx+=(long long)min(r+1,upper[i]);
long long m=k-sx;
if(m>0)
sx=0;
for(i=1;i<=n;i++)
sx+=min(r,upper[i]);
m=k-sx;
int p=0;
for(i=1;i<=n;i++)
}sort(sa+1,sa+1+p);
p=0;
for(i=1;i<=n;i++)
}for(i=1;ians[i+1])
}for(i=1;i<=n-1;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[i]);
return 0;
}
bzoj 5347 氣泡排序
考慮到最後a i 都要等於i,並且每個 a i i 的a i 一輪最多向前走一次,所以局數至少是 max。又因為對於a i i來說,一輪不動意味著 a i 1 a i 所以 i 1 a i 1 是 i a i 的,所以要麼該位置不是max的位置,要麼就會向前移動,所以局數正好就是 max啦。incl...
BZOJ 5416 Noi2018 氣泡排序
bzoj 5416 noi2018 氣泡排序 dp 組合數 樹狀陣列 好題。合法的排列的交換次數剛好是交換次數的下界,也就是說不能有多餘的交換。也就是對於ai這個數,只能從i到ai這乙個方向走。考慮x,y,z三個數 x y z y需要和x z各交換一次,這顯然不能使y這個數滿足只向乙個方向移動這個條...
氣泡排序 排序 氣泡排序
既然寫了計組思來想去便打算把資料結構也寫下來,寫的時候總是發現看的時候無法發現的問題,受益良多。交換排序的基本思想 exchange until sorted 順序,分支,迴圈 注意偽 的熟悉 下面介紹兩種交換演算法 首先進行聯想,用乙個圖進行輔助聯想 水冒泡過程 頂部是陣列的begin,底部理解為...