题目

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?

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.

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 resulting 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.

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

题目分析

已知原始数组a,和对a排序过程中数组b,判断是归并排序还是插入排序,并打印再进行一轮排序后的结果

解题思路

判断是归并排序还是插入排序--插入排序过程中数组特点:第一个非升序数字(假设其索引为i)后的剩余数字都与原数组中相同位置数字相同

思路 01

  1. 如果是插入排序,对[0,i+1]的数字进行排序就是下一轮插入排序的结果
  2. 如果是归并排序,从原始数组使用非递归归并代码执行归并过程,并在每一轮判断排序结果是否已经是题目中已知的数组b,若是,则再进行一轮归并即可得出结果

思路 02

  1. 对原始数组分别进行插入排序和归并排序,在每一轮结束后,判断排序结果是否已经是题目中已知的数组b,若是,则再进行一轮排序即可得出结果

Code

Code 01

#include <iostream>
#include <algorithm>
using namespace std;
int main() {
// 1 接收输入
int n, a[100], b[100], i, j;
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
cin >> b[i];
// 2 判断是哪种排序
for (i = 0; i < n - 1 && b[i] <= b[i + 1]; i++); //找到第一个非升序数字下标
for (j = i + 1; a[j] == b[j] && j < n; j++); //从非升序数字后,开始找第一个下标相同元素不同的下标
if (j == n) {// 若第一个非升序数字后所有元素都与原数组相同,是插入排序
cout << "Insertion Sort" << endl;
sort(a, a + i + 2);
} else {// 归并排序
cout << "Merge Sort" << endl;
int k = 1, flag = 1;
while(flag) {
flag = 0;
for (i = 0; i < n; i++) {
if (a[i] != b[i])
flag = 1;
}
k = k * 2;
for (i = 0; i < n / k; i++) // 对左边模拟归并排序
sort(a + i * k, a + (i + 1) * k);
sort(a + n / k * k, a + n); // 如果有右边剩余,对齐进行排序
}
}
// 3 打印数组
for (j = 0; j < n; j++) {
if (j != 0) printf(" ");
printf("%d", a[j]);
}
return 0;
}

Code 02

#include <iostream>
#include <algorithm>
using namespace std;
const int N=111;
int origin[N],tempOri[N],changed[N];
int n; //元素个数
// 判断数组是否相等
bool isSame(int A[],int B[]) {
for(int i=0; i<n; i++)
if(A[i]!=B[i])return false;
return true;
}
// 打印数组
void showArray(int A[]) {
for(int i=0; i<n; i++) {
printf("%d",A[i]);
if(i<n-1)printf(" ");
}
printf("\n");
}
// 插入排序
bool insert_sort() {
bool flag = false;
for(int i=1; i<n; i++) {
if(i!=1&&isSame(tempOri,changed)) {
flag = true;
}
// 写法一:
int j,temp = tempOri[i];
for(j=i-1; j>=0; j--) {
if(temp>=tempOri[j])break;
else tempOri[j+1]=tempOri[j];
}
tempOri[j+1]=temp;
// 写法二:
// int j=i,temp = tempOri[i];
// while(j>0&&tempOri[j-1]>temp){
// tempOri[j]=tempOri[j-1];
// j--;
// }
// tempOri[j]=temp;
if(flag)return true;
}
return false;
}
// 归并排序
void merge_sort() {
bool flag = false;
for(int step=2; step/2<=n; step*=2) { // 每次步长扩大一倍
if(step!=2&&isSame(tempOri,changed))
flag = true;
for(int i=0; i<n; i+=step) // 一轮排序,分成很多step组
sort(tempOri+i,tempOri+min(i+step,n)); //每个step组升序排序
if(flag) {
showArray(tempOri);
return;
}
}
}
int main(int argc, char * argv[]) {
scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%d",&origin[i]);
tempOri[i]=origin[i];
}
for(int i=0; i<n; i++) {
scanf("%d",&changed[i]);
}
if(insert_sort()) {
printf("Insertion Sort\n");
showArray(tempOri);
} else {
printf("Merge Sort\n");
for(int i=0; i<n; i++) {
tempOri[i]=origin[i]; //还原tempOri数组
}
merge_sort();
}
return 0;
}

PAT Advanced 1089 Insert or Merge (25) [two pointers]的更多相关文章

  1. PAT甲级:1089 Insert or Merge (25分)

    PAT甲级:1089 Insert or Merge (25分) 题干 According to Wikipedia: Insertion sort iterates, consuming one i ...

  2. PAT甲级1089. Insert or Merge

    PAT甲级1089. Insert or Merge 题意: 根据维基百科: 插入排序迭代,消耗一个输入元素每次重复,并增加排序的输出列表.每次迭代,插入排序从输入数据中删除一个元素,在排序列表中找到 ...

  3. PAT (Advanced Level) 1089. Insert or Merge (25)

    简单题.模拟一下即可. #include<cstdio> #include<cstring> #include<cmath> #include<vector& ...

  4. PAT 1089. Insert or Merge (25)

    According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...

  5. 【PAT甲级】1089 Insert or Merge (25 分)(插入排序和归并排序)

    题意: 输入一个正整数N(<=100),接着输入两行N个整数,第一行表示初始序列,第二行表示经过一定程度的排序后的序列.输出这个序列是由插入排序或者归并排序得到的,并且下一行输出经过再一次排序操 ...

  6. 1089. Insert or Merge (25)

    题目如下: According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, ...

  7. 1089. Insert or Merge (25)-判断插入排序还是归并排序

    判断插入排序很好判断,不是的话那就是归并排序了. 由于归并排序区间是2.4.8开始递增的,所以要判断给出的归并排序执行到哪一步,就要k从2开始枚举. 然后再对每个子区间进行一下sort即可. #inc ...

  8. 1089 Insert or Merge (25 分)

    According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...

  9. 1089 Insert or Merge (25分)

    According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...

随机推荐

  1. 019-PHP创建目录函数

    <?php if (mkdir("myDir1", 0777)) //创建目录的函数 { print("目录创建成功"); //目录建立成功 } else ...

  2. 第一个flink application

    导入maven依赖 需要注意的是,如果使用scala写程序,导入的依赖跟java是不一样的 Maven Dependencies You can add the following dependenc ...

  3. v2??? 替换协议

    输入 v2??? 命令,选择修改 v2??? 配置, 然后选择修改传输协议, 可以选择 mKcp_wechat-video .然后重新生成 vmess,放入客户端使用.

  4. 前端01 HTML5

    01工具使用 Sublime插件安装和使用 2Sublime插件安装和使用.pcf 3Sublime插件安装与卸载.pcf 4Sublime安装markdown插件.pcf 使用typora生成pdf ...

  5. P1036 跟奥巴马一起编程

    转跳点:

  6. PHP常用的数学函数和字符串函数

    PHP常用函数总结 数学函数 1.abs(): 求绝对值 $abs = abs(-4.2); //4.2 数字绝对值数字 2.ceil(): 进一法取整 echo ceil(9.999); // 10 ...

  7. VUE.js入门学习(3)-深入理解VUE组建

    1.使用组件的细节点 (1)is="模版名" (2)在子组建定义data的时候,data必须是一个函数,而不能是一个对象,每个子组建都有自己的数据存储.之间不会相互影响. (3)操 ...

  8. java获取配置文件信息

    两个类 package com.censoft.util; import java.util.Properties; import java.io.*; import java.util.ArrayL ...

  9. 10. react 基础 ref 的使用 及 React 16 的生命周期函数 及 生命周期函数使用场景

    一. ref 的使用 ( 直接获取 DOM 元素 ) 在 input 标签上 可以使用 ref 属性 获取当前DOM节点 eg: import React , { Component, Fragmen ...

  10. filter的原理(转)

    今天学习了一下javaweb开发中的Filter技术,于是在网上搜了一下相关资料,发现这篇博客写的很不错,于是希望能转载过来以备以后继续学习之用.(原:http://www.cnblogs.com/x ...