PAT-A,題目地址:https://www.patest.cn/contests/pat-a-practise/1089
思路:
- 這道題首先要判斷清楚用的是哪種排序,顯然,驗證插入排序要簡單一些,通過sample就可以觀察出,插入排序到一半時,前若干個元素是從大到小排列的,然后之后的元素都在其初始的位置。如果滿足這個規律,就是插入排序,否則就是歸并排序
- 如果是插入排序,先找出所有n個元素中,已經排好序的有insert_stage個,然后對于第insert_stage+1個元素,給其找個合適的位置,然后依次輸出即可
- 如果是歸并排序,則要找出歸并到了第幾步,即當前已經sorted的數組的大小是多少,然后把這個數字擴大一倍,進行歸并,這里我比較偷懶,用了sort函數
代碼
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int n;
int init[100]; //初始數組
int inter[100]; //排序到一半的數組
bool is_merge = false;
cin >> n;
for(int i = 0; i < n; i++){
cin >> init[i];
}
for(int i = 0; i < n; i++){
cin >> inter[i];
}
int insert_stage = 1;
for(int i = 1; i < n; i++){
if(inter[i] >= inter[i-1]);
else{
insert_stage = i; //有insert_stage個數是已經排好序的
break;
}
}
for(int i = insert_stage; i < n; i++){ //在此之后的數必須還處于原來的位置
if(inter[i] == init[i]);
else{
is_merge = true;
break;
}
}
if(!is_merge){ //如果是插入排序
cout << "Insertion Sort" << endl;
int index = 0;
for(int i = 0; i < n; i++){
if(inter[i] < inter[insert_stage])
cout << inter[i] << " ";
else{
index = i; //下一步要把下標為index的數插入到sorted的數組中
break;
}
}
cout << inter[insert_stage] << " ";
for(int i = index; i < insert_stage; i++){
cout << inter[i];
if(i != n-1)
cout << " ";
}
for(int i = insert_stage + 1; i < n; i++){ //剩下的還未排序的數
cout << inter[i];
if(i != n-1)
cout << " ";
}
cout << endl;
}
else{ //如果是歸并排序
cout << "Merge Sort" << endl;
bool right = true;
int group_size = 64;
while(group_size > n)
group_size /= 2;
while(1){
int round = n / group_size + 1;
right = true; //排好序的數組大小是不是groug_size
for(int i = 0; i < round; i++){
for(int j = i * group_size; j < n && j < (i+1) * group_size; j++){
if(j == i * group_size || inter[j] > inter[j-1]); //組內是不是sorted
else{
right = false;
break;
}
}
if(!right)
break;
}
if(right || group_size == 1)
break;
group_size /= 2;
}
group_size *= 2; //把group_size擴大一倍。代表下一步排好序的數組大小
int round = n / group_size + 1;
for(int i = 0; i < round; i++){ //對每個子數組進行歸并
int start = i * group_size;
int end = n < (i+1) * group_size ? n : (i+1) * group_size;
sort(&inter[start], &inter[end]);
}
for(int i = 0; i < n; i++){
cout << inter[i];
if(i != n-1)
cout << " ";
}
cout << endl;
}
return 0;
}