whenever

  • Home

  • Tags21

  • Categories6

  • Archives122

  • About

PAT乙级1035 || 插入与归并(详解,C/C++示例,测试点分析)

Posted on 2019-09-30 In PAT

插入与归并

题目描述

根据维基百科的定义:

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

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

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

输入格式

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

输出格式

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

输入样例1

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

输出样例1

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

输入样例2

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

输出样例2

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

问题解决

解题思想

解决此题的主要思想就是拿每趟排序的结果(插入排序或者归并排序)与所给中间序列进行比较,若某排序方法的某一趟排序结果与给定的中间序列相等,则输出该排序方法及下一趟排序的结果。

无论是插入排序还是归并排序,我们理解了它们的排序思想之后,其实不用完整的写出其具体的排序过程,因为题目只要求知道每一趟排序结束时的序列,故可用sort()函数来实现每一趟排序,这样会导致时间效率低一些,但本题N最大不超过100,这种影响便可忽略了。

代码示例(C/C++)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <cstdio>
#include <algorithm>
#define MAXN 101
using namespace std;
bool Is_Insert_Sort(int a[],int b[],int n);
bool Is_Merge_Sort(int a[],int b[],int n);
bool Is_Equal(int a[],int b[],int n);
void Print_Array(int a[],int n);
int main()
{
int n,a1[MAXN],a2[MAXN],b[MAXN]; //用两个数组a1[],a2[]来接收原始序列
scanf("%d",&n);
for(int i = 0; i < n; i++){
scanf("%d",&a1[i]);
a2[i] = a1[i];
}
for(int i = 0; i < n; i++){
scanf("%d",&b[i]);
}
if(Is_Insert_Sort(a1,b,n)){ //先判断是否为插入排序的中间序列
printf("Insertion Sort\n");
Print_Array(a1,n);
}
else if(Is_Merge_Sort(a2,b,n)){ //若不是插入排序的中间序列则用a2[]作实参继续判断是否为归并
printf("Merge Sort\n");
Print_Array(a2,n);
}
return 0;
}
//判断是否为插入排序的某一趟
bool Is_Insert_Sort(int a[],int b[],int n)
{
for(int i = 1; i <= n; i++){ //每一个i对应一趟
sort(a,a + i + 1); //插入排序的第i趟
if(Is_Equal(a,b,n)){
sort(a,a + i + 2); //某趟排序后与给定中间序列相等则再进行一趟
return 1;
}
}
return 0;
}
//判断是否为归并排序的某一趟
bool Is_Merge_Sort(int a[],int b[],int n)
{
for(int i = 2; i / 2 <= n; i *= 2){
for(int j = 0; j < n; j += i){//一趟归并排序
sort(a + j,a + min(j + i,n));
}
if(Is_Equal(a,b,n)){ //某趟排序后与给定中间序列相等则再进行一趟
i *= 2;
for(int j = 0; j < n; j += i){
sort(a + j,a + min(j + i,n));
}
return 1;
}
}
return 0;
}
//判断数组a与b的对应元素是否相等
bool Is_Equal(int a[],int b[],int n)
{
for(int i = 0; i < n; i++){
if(a[i] != b[i]){
return 0;
}
}
return 1;
}
//输出数组元素
void Print_Array(int a[],int n)
{
for(int i = 0; i < n; i++){
printf("%d",a[i]);
if(i != n - 1){
printf(" ");
}
}
}

题目来源:PAT乙级1035
作者:CHEN, Yue
单位:浙江大学

稀罕作者
Mengzhao Wang WeChat Pay

WeChat Pay

Mengzhao Wang Alipay

Alipay

# C/C++ # PAT # 编程
PAT乙级1034 || 有理数四则运算(详解,C/C++示例,测试点分析)
PAT乙级1036 || 跟奥巴马一起编程(详解,C/C++示例,测试点分析)
  • Table of Contents
  • Overview
Mengzhao Wang

Mengzhao Wang

Try? All the way !
122 posts
6 categories
21 tags
  1. 1. 插入与归并
    1. 1.1. 题目描述
    2. 1.2. 输入格式
    3. 1.3. 输出格式
    4. 1.4. 输入样例1
    5. 1.5. 输出样例1
    6. 1.6. 输入样例2
    7. 1.7. 输出样例2
    8. 1.8. 问题解决
      1. 1.8.1. 解题思想
      2. 1.8.2. 代码示例(C/C++)
© 2021 Mengzhao Wang