1089. Insert or Merge (25)

PAT-A,题目地址:https://www.patest.cn/contests/pat-a-practise/1089

思路:

  1. 这道题首先要判断清楚用的是哪种排序,显然,验证插入排序要简单一些,通过sample就可以观察出,插入排序到一半时,前若干个元素是从大到小排列的,然后之后的元素都在其初始的位置。如果满足这个规律,就是插入排序,否则就是归并排序
  2. 如果是插入排序,先找出所有n个元素中,已经排好序的有insert_stage个,然后对于第insert_stage+1个元素,给其找个合适的位置,然后依次输出即可
  3. 如果是归并排序,则要找出归并到了第几步,即当前已经sorted的数组的大小是多少,然后把这个数字扩大一倍,进行归并,这里我比较偷懒,用了sort函数

代码

#include 
#include 

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

你可能感兴趣的:(1089. Insert or Merge (25))