題目就是給兩個序列,第一個是排序前的,第二個是排序中的,判斷它是采用插入排序還是堆排序,並且輸出下一次操作后的序列。
插入排序的特點就是,前面是從小到大排列的,后面就與原序列相同。
堆排序的特點就是,后面是從小到大排列的最大的幾個數p~n-1,前面第一位則是p-1。
所以只要先按照插入排序的特點來判斷是否為插入排序,接下來再進行操作就可以了,這里要手動寫下最大堆的更新操作。
代碼:

#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> /* 之前一直WA的原因是,用for循環寫尋找idx一開始就寫錯了。。。 找了整個序列的<,應該是找反例>從而跳出for循環,或者直接加到條件里。 比如: 一開始這么寫, for(int i=0;i<n;i++){ if(num2[i]<=num2[i+1]) idx++; } 正確應該是: for(idx=0;idx<n-1 && num2[idx]<=num2[idx+1];idx++); 暈死。。。腦子糊塗了 */ using namespace std; const int maxn=105; int heap[maxn]; int heap_size=0; void swaps(int &a,int &b){ int tmp; tmp=a; a=b; b=tmp; } void heap_update(int i){ int bigger=i; int l=(i<<1)+1; int r=(i<<1)+2; if(l<heap_size && heap[l]>heap[i]) bigger=l; if(r<heap_size && heap[r]>heap[bigger]) bigger=r; if(bigger!=i){ swaps(heap[i],heap[bigger]); heap_update(bigger); } } void heap_pop(){ if(heap_size>=1){ swaps(heap[0],heap[heap_size-1]); //take the max to the rear. heap_size--; heap_update(0); } } int main() { int n; int num[maxn],num2[maxn]; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&num[i]); } for(int i=0;i<n;i++){ scanf("%d",&num2[i]); } int idx; for(idx=0;idx<n-1 && num2[idx]<=num2[idx+1];idx++); int p=idx+1; for(;p<n && num[p]==num2[p];p++); if(p==n){ sort(num2,num2+idx+2); //相當於將num[idx+1]插入到前面排序 printf("Insertion Sort\n"); for(int i=0;i<n-1;i++) printf("%d ",num2[i]); printf("%d",num2[n-1]); } else{ int sortedsize=0; int tmpnum[maxn]; for(int i=0;i<n;i++) tmpnum[i]=num[i]; sort(tmpnum,tmpnum+n); p=n-1; /* 看了別人網上有寫第三行AC的, 但按道理來說,如果樣例2的第二個序列是6 4 5 0 1 2 3 7 8 9,那明顯第三行就不對額。 10 3 1 2 8 7 5 9 4 6 0 6 4 5 0 1 2 3 7 8 9 Heap Sort 5 4 3 0 1 2 6 7 8 9 (第一行的輸出) 5 4 0 6 1 2 3 7 8 9 (第三行的輸出) */ for(;p>=0 && num2[p]==tmpnum[p];p--); //for(;p>=1 && num2[p]>=num2[0];p--); //for(;p>=1 && num2[p]>=num2[p-1];p--); //個人認為應該是過不了的。。。但卻AC了 heap_size=p+1; for(int i=0;i<n;i++) heap[i]=num2[i]; heap_pop(); printf("Heap Sort\n"); for(int i=0;i<n-1;i++){ printf("%d ",heap[i]); } printf("%d",heap[n-1]); } return 0; }