*PAT_甲級_1089 Insert or Merge (25point(s)) (C++)【插入排序/歸併排序】

目錄

1,題目描述

題目描述

注意

2,思路

3,AC代碼

4,解題過程

第一搏


1,題目描述

  • consuming:強烈的; 重要的; 耗費(燃料、能量、時間等); 吃; 喝; 飲; 使充滿(強烈的感情);
  •  

Sample Input 1:

10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0

 

Sample Output 1:

Insertion Sort
1 2 3 5 7 8 9 4 6 0

 

Sample Input 2:

10
3 1 2 8 7 5 9 4 0 6
1 3 2 8 5 7 4 9 0 6

 

Sample Output 2:

Merge Sort
1 2 3 8 4 5 7 9 0 6

題目描述

根據給出的原始序列和部分排序的序列,判斷是什麼排序方法,並輸出下一步排序結果。

 

注意

  • 真正的歸併排序,是類似於樹的DFS遍歷(左邊部分排序,右邊部分排序,兩者合併作爲新的左邊部分,再繼續下去),而題目中的“一步”是類似於從底向上的層次遍歷(每一步,就把當前層次的所有小區間內的數進行排序);以題目中的例子爲例(帶顏色的爲每“一步”中改動的部分):
  • memcpy(dest,source,size):將數組source複製給數組dest,size表示數組source的大小;(來自大神@日沉雲起【pat甲級1089 Insert or Merge (25)、乙級1035 插入與歸併(25)】
  • equal(beg1,end1,beg2):比較兩個序列對應位置上的元素是否相等,相等則返回true;否則返回false。beg1,end1,beg2均爲迭代器,[beg1,end1]確定了序列1的首尾區間,beg2確定了序列2的起始位置;

 

2,思路

參考@日沉雲起【pat甲級1089 Insert or Merge (25)、乙級1035 插入與歸併(25)】

  1. 將原始序列init拷貝到A中,對A進行操作;
  2. 模擬插入排序:每次對前i個元素排序(i從1開始,即排序元素數目從2開始),若與tar數組匹配成功,則再進行一步:
  3. 模擬歸併排序:(嚴格意義上來說,這並不是歸併排序,而是利用歸併的思想,進行的排序)按照區間長度2,4,8……進行排序

 

3,AC代碼

代碼簡潔,邏輯清晰!再膜大神@日沉雲起!

#include<bits/stdc++.h>
using namespace std;
int N, A[102], init[102], tar[102];
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    scanf("%d", &N);
    for(int i = 0; i < N; i++)
        scanf("%d", &init[i]);
    for(int i = 0; i < N; i++)
        scanf("%d", &tar[i]);
    memcpy(A, init, sizeof(init));      //拷貝數組
    bool flag = false;
    for(int i = 1; i < N; i++){
        sort(A, A + i + 1);             //sort時不包括末尾A+i+1
        if(equal(A, A + N, tar)){       //比較時是比較全部數字A + N
            flag = true;                //不要寫成==
            printf("Insertion Sort\n");
            sort(A, A + i + 2);
            break;
        }
    }
    if(!flag){
        memcpy(A, init, sizeof(init));  //拷貝數組
        printf("Merge Sort\n");
        for(int i = 2; i < N; i *= 2){  //每次排序的小區間擴大一倍
            for(int j = 0; j < N; j += i)
                sort(A + j, i+j>N ? A+N : A+i+j);           //666!!!
            if(equal(A, A + N, tar)){
                for(int j = 0; j < N; j += 2 * i)
                    sort(A + j, j+2*i>N ? A+N : A+j+2*i);   //666!!!
                break;
            }
        }
    }
    printf("%d", A[0]);
    for(int i = 1; i < N; i++)
        printf(" %d", A[i]);
    return 0;
}

4,解題過程

第一搏

本想着自己模擬一遍插入排序和歸併排序,但是,,,感覺太繁瑣了,上網請教大神!果然還是有很多的黑科技的(●ˇ∀ˇ●)

  • memcpy(dest,source,size):將數組source複製給數組dest,size表示數組source的大小
  • equal(beg1,end1,beg2):比較兩個序列對應位置上的元素是否相等,相等則返回true;否則返回false。beg1,end1,beg2均爲迭代器,[beg1,end1]確定了序列1的首尾區間,beg2確定了序列2的起始位置

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章