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;
}