【題意】
給定一個序列的初始狀態和經過某種排序幾個步驟之後的結果,要求判斷是插入排序還是堆排序,並輸出執行下一個步驟之後的結果。
【題解】
不清楚插入排序和堆排序的請移步:八大排序
首先,我們根據排序過程中得到的序列判斷是哪種排序。怎麼判斷呢?如果能把序列分成兩段,前一段是有序的,後一段是跟原序列相同的,這樣就是插入排序;否則是堆排序。如果是插入排序,那麼我們只需要將下一個元素加入到前一段中排個序即可;如果是堆排序,我們只需要尋找到最後一個沒完成排序的位置,交換首尾的位置,再把這個位置之前的所有元素依次向下調整爲大頂堆即可。
【代碼】
#include <bits/stdc++.h>
using namespace std;
int a[105],b[105];
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
int l,r,f=1;
for(l=1;l<=n;l++)
if(b[l]>b[l+1]) break;
for(r=n;r>l;r--)
if(a[r]!=b[r]) f=0;
if(f){
printf("Insertion Sort\n");
sort(b+1,b+l+2);
}
else{
printf("Heap Sort\n");
sort(a+1,a+1+n);
for(l=n;b[l]==a[l];l--);
swap(b[1],b[l]);
l--;
for(int i=l/2;i>=1;i--){
int flag=1,pos=i;
while(flag){
int t=pos;
if(pos*2<=l&&b[t]<b[pos*2]) t=pos*2;
if(pos*2+1<=l&&b[t]<b[pos*2+1]) t=pos*2+1;
if(t!=pos){
swap(b[t],b[pos]);
pos=t;
}
else flag=0;
}
}
}
for(int i=1;i<=n;i++)
printf(i<n?"%d ":"%d\n",b[i]);
return 0;
}