PAT-A1089/B1035 Insert or Merge/插入与归并 题目内容及题解

According to Wikipedia:

Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.

Merge sort works as follows: Divide the unsorted list into N sublists, each containing 1 element (a list of 1 element is considered sorted). Then repeatedly merge two adjacent sublists to produce new sorted sublists until there is only 1 sublist remaining.

Now given the initial sequence of integers, together with a sequence which is a result of several iterations of some sorting method, can you tell which sorting method we are using?

根据维基百科的定义:

插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。

归并排序进行如下迭代操作:首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。

现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤100). Then in the next line, N integers are given as the initial sequence. The last line contains the partially sorted sequence of the N numbers. It is assumed that the target sequence is always ascending. All the numbers in a line are separated by a space.

输入在第一行给出正整数 N (≤100);随后一行给出原始序列的 N 个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。

Output Specification:

For each test case, print in the first line either "Insertion Sort" or "Merge Sort" to indicate the method used to obtain the partial result. Then run this method for one more iteration and output in the second line the resuling sequence. It is guaranteed that the answer is unique for each test case. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

首先在第 1 行中输出Insertion Sort表示插入排序、或Merge Sort表示归并排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格。

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

解题思路

  1. 读入初始序列和排序中间序列;
  2. 通过检查排序是否符合插入排序特征(前m项排好序,其他项无影响)确定排序方式;
  3. 如为插入排序,则根据已有序数据数量再后移一位,并排序;
  4. 如为归并排序,则根据已有序数据判断当前步长,并将其翻倍后排序;
  5. 输出排序结果并返回零值。

代码

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

int N,m;
vector<int> Origin,Sorted,Test;

void Init(){
    int i,a;
    scanf("%d",&N);
    for(i=0;i<N;i++){
        scanf("%d",&a);
        Origin.push_back(a);
        Test.push_back(a);
    }
    for(i=0;i<N;i++){
        scanf("%d",&a);
        Sorted.push_back(a);
    }
}

int isSort(int low,int high){
    int i;
    for(i=low;i<high-1;i++){
        if(Sorted[i]>Sorted[i+1]){
            break;
        }
    }
    if(i<high-1){
        return 0;
    }else{
        return 1;
    }
}

int check(){
    int i;
    m=1;
    for(i=1;i<N;i++){
        if(Sorted[i]>=Sorted[i-1]){
            m++;
        }else{
            break;
        }
    }
    sort(Test.begin(),Test.begin()+m);
    for(i=0;i<N;i++){
        if(Test[i]!=Sorted[i]){
            break;
        }
    }
    if(i==N){
        return 1;
    }else{
        return 0;
    }
}//插入为1,归并为0

void Print(){
    int i;
    for(i=0;i<N;i++){
        printf("%d",Sorted[i]);
        if(i<N-1){
            printf(" ");
        }else{
            printf("\n");
        }
    }
}

void Insertation(){
    printf("Insertion Sort\n");
    if(m<N){
        sort(Sorted.begin(),Sorted.begin()+m+1);
    }
}

void MergeSort(){
    int i,k;
    printf("Merge Sort\n");
    m*=2;
    k=N/m;
    for(i=0;i<k;i++){
        sort(Sorted.begin()+i*m,Sorted.begin()+(i+1)*m);
    }
    if(N%m){
        sort(Sorted.begin()+i*m,Sorted.end());
    }
} 
int main(){
    int i,flag,k;
    Init();
    if(check()){
        //插入
        Insertation();
    }else{
        while(1){
            flag=1;
            k=N/m;
            for(i=0;i<k;i++){
                if(isSort(i*m,(i+1)*m)==0){
                    flag=0;
                    break;
                }
            }
            if(isSort(i*m,N)==0){
                flag=0;
            }
            if(flag==0){
                m/=2;
            }else{
                break;
            }
        }
        //归并
        MergeSort();
    }
    Print();
    return 0;
} 

运行结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值