题目

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. C# 读取CSV格式数据 读取为DataTable类型

    先贴代码: using System.Data;using System.Data.OleDb; static void Main(string[] args) { var strpath = Sys ...

  2. 【iOS】Swift4.0 GCD的使用笔记

    https://www.jianshu.com/p/47e45367e524 前言 在Swift4.0版本中GCD的常用方法还是有比较大的改动,这里做个简单的整理汇总. GCD的队列 队列是一种遵循先 ...

  3. spring源码 BeanFactory根接口

    /* * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Vers ...

  4. AI 人工智能产业园路口-----dp

    北京市商汤科技开发有限公司建立了新的 AI 人工智能产业园,这个产业园区里有 nn 个路口,由 n - 1n−1 条道路连通.第 ii 条道路连接路口 u_iui​ 和 v_ivi​. 每个路口都布有 ...

  5. Arduino - -- 串口双向通信

    需要用到Arduino UNO的串口双向通信功能,以下源码: int val; void setup() {   Serial.begin(9600); // opensserial port, se ...

  6. BZOJ:2242: [SDOI2011]计算器

    题解:BSGS 问题:map空间 BSGS判无解 a%p!=0 0与最小非负整数 有区别 函数传参类型转换int->long long long long ->int; 费马小定理充分必要 ...

  7. 全面掌握Nginx配置+快速搭建高可用架构 一 random_index_module 随机主页

    修改default.conf 保存重载Nginx,完成配置 自动随机选择主页 string要替换的内容,replacement表示替换后的内容 示例 效果,只替换了第一个 如果要替换所有的,需要用到s ...

  8. 51nod1414 冰雕(暴力枚举)

    题目是这样的: 1414 冰雕 白兰大学正在准备庆祝成立256周年.特别任命副校长来准备校园的装扮. 校园的中心竖立着n个冰雕.这些雕像被排在一个等分圆上,因此他们形成了一个正n多边形.这些冰雕被顺针 ...

  9. Android自定义View——简单实现边缘凹凸电子票效果

        View继承LinearLayout,在View的上下边缘画出白色的圆形即可,这里只要计算出圆的个数和圆的循环规律即可,下面请看分析 我们取卡片的前2个凹凸来看,将其分为四部分,并且两部分为循 ...

  10. NET CLR via C#(第4版)第4章 类型基础

    本章内容: 1 所有类型都从System.Object派生 2 类型转换 3 命名空间和程序集 4 运行时的相互关系   本章讲述使用类型和CLR时需掌握的基础知识.具体地说,要讨论所有类型都具有的一 ...