题目

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. 十九、SAP查询所有数据库表的所有数据

    一.我们打款SAP自带的一个演示数据库SCARR 二.表结构如下 三.代码如下 四.执行结果如下 我们对比一下数据库的内容,很perfect 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微 ...

  2. hdu4632 Palindrome subsequence 回文子序列个数 区间dp

    Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/ ...

  3. python EasyUI + Django--整合 CSRF 防护去除

    先来张完整图: 关于Django 得CSRF  中间件      防护   GET 是不做CSRF验证得   但POST 默认验证  $.cookie('csrftoken'))    "v ...

  4. centos破解压缩文件密码

    rarcrack是linux系统端的一款破解加密压缩包的工具,rarcrack使用的穷举法进行破解已经加密的rar.zip和7z压缩包,支持设置多线程,和文件类型进行破解. 1.rarcrack下载页 ...

  5. taro编译的时候报 exports.pRimraf = util_1.promisify(rimraf); 错误

    C:\Users\1\AppData\Roaming\npm\node_modules\@tarojs\cli\dist\h5\helper.js:8 exports.pRimraf = util_1 ...

  6. BlackArch Linux 2019.06.01 宣布发布

    导读 BlackArch Linux是一个基于Arch Linux的发行版,专为渗透测试人员和安全研究人员设计,并包含大量渗透测试和安全实用程序,已宣布发布2019.06.01版本. BlackArc ...

  7. 封装localStorage设置,获取,移除方法

    export const local = { set(key, value) { localStorage.setItem(key, JSON.stringify(value)); }, get(ke ...

  8. Django xadmin图片上传与缩略图处理

    基本摘要 用python django开发时,个人选中Xadmin后台管理系统框架,因为它*内置功能丰富, 不仅提供了基本的CRUD功能,还内置了丰富的插件功能.包括数据导出.书签.图表.数据添加向导 ...

  9. Java IO 乱码

    InputStreamReader isr = new InputStreamReader(new FileInputStream("./test/垃圾短信训练集80W条.txt" ...

  10. Alpha版(内部测试版发布)

    使用说明: 使用环境:android 5.0以上 使用流程: 1.注册与登陆 可以通过游客和用户两个模式登陆 用户模式:进入后会有模拟位置图,每一环代表不同的距离 底部菜单栏表示不同的功能,消息栏可以 ...