题目如下:

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
1 2 3 8 4 5 7 9 0 6

题目要求对给定序列的排序过程中序列进行处理,判断出是归并排序还是插入排序,并且要输出再进行一次此种排序后的结果。

【方法一】

要判断插入排序和归并排序,只需要看有序位置的不同,归并排序是分组有序,而插入排序是从前到后部分有序,通过这一特性,可以去找序列中的最小有序对,例如题目给出的第二组数据1 3 2 8 5 7 4 9 0 6,我们在1 3这个子序列得到有序子序列长度为2,向后处理可以发现每2个组成的子序列都是有序的,并且两两之间无序,因此是归并排序的特征。看第一组数据 1 2 3 7 8 5 9 4 6 0,如果从1 2 3 判断长为3的有序对,发现不满足。再尝试2为长度的,依然不满足,因此不是归并排序,而从前到后部分有序,因此是插入排序。

这时一种区分两种排序的方法,通过此种方法区分后再调用相应的排序函数,利用vector的==(系统自带)来判断序列的吻合性,然后再进行一步即可。

【方法二】

将插入排序拆分成按步进行,归并排序也采用非递归形式,非递归归并通过step=1开始,从长度为1的小区间开始归并,每次step+1。为了合并小区间,可以利用系统的inplace_merge函数,只要指定子序列的迭代器的头、中、尾,即可归并两序列。

此方法不必像方法一那样判断,而是先执行插入排序,找序列吻合,找到则再排输出,否则再尝试归并,这个方法比较简单,我比较完整的参考了zzyazzy的代码,如下:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; bool perInsertSort(vector<int> &src,vector<int> &dest,int start)
{
int pos = start;
int poit = src[start];
for(int j= start -1;j>=0;--j){//找出插入位置
if(src[j] > poit) {
pos = j;
}else{
break;
}
}
for(int j=start -1;j>=pos;--j){
src[j+1]=src[j];
}
src[pos]=poit;
if(src==dest) return true;
return false;
} void mergeSort(vector<int> &src,int step)
{
int len = src.size();
if(step >= len) return ;//子区间的长度已经大于src的长度
int i = 0;
while(i<len){
vector<int>::iterator iter = src.begin();
int start = i;
int middle = i+step;
int end = middle+step;
middle =(middle >= len ? len:middle);
end = (end >= len ? len:end);
inplace_merge(iter+start,iter+middle,iter+end);
i=end;
}
} void print(const vector<int> &src)
{
bool first = true;
for(int i=0;i<src.size();++i){
if(first){
cout<<src[i];
first = false;
}else{
cout<<" "<<src[i];
}
}
} int main()
{
int n;
cin>>n;
int x;
vector<int> src,dest;
int repeat = n;
while(repeat --){
cin>>x;
src.push_back(x);
}
repeat = n;
while(repeat --){
cin>>x;
dest.push_back(x);
}
vector<int> temp(src.begin(),src.end()); // 备份原来的数据,如果不是插入,还需要拿到原数据处理,。
bool isInsertSort=false;
for(int i = 1;i < src.size(); ++i){
isInsertSort = perInsertSort(src,dest,i);
if(isInsertSort){
cout<<"Insertion Sort"<<endl;
if(i + 1 <= src.size()){ // 需要继续排序
perInsertSort(src,dest,i+1);
print(src);
cout<<endl;
break;
}else{ // 已经是最后一次排序,则直接输出结果。
print(src);
cout << endl;
}
}
}
if(!isInsertSort){
int step = 1;
while(step < temp.size()){
if(temp==dest){
cout<<"Merge Sort"<<endl;
mergeSort(temp,step);
print(temp);
cout<<endl;
break;
}
mergeSort(temp,step);
step *= 2;
}
}
return 0;
}

1089. Insert or Merge (25)的更多相关文章

  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 (25)

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

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

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

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

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

  5. 1089 Insert or Merge (25 分)

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

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

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

  7. PAT Advanced 1089 Insert or Merge (25) [two pointers]

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

  8. 1089 Insert or Merge (25分)

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

  9. pat1089. Insert or Merge (25)

    1089. Insert or Merge (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Accor ...

随机推荐

  1. [SDOI2010]地精部落

    题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为N的山脉H可分为从左到右的N段,每段有一个[b][u]独一无二[/u][/b]的高度Hi, ...

  2. 【UOJ UNR #1】争夺圣杯

    来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 考虑直接对每个数字,统计它会产生的贡献. 单调栈求出每个数字左边第一个大等于他的数,右边第一个大于他的 (注意只能有一边取等) 假设左 ...

  3. JVM学习记录-对象已死吗

    前言 先来回顾一下,在jvm运行时数据区,分为两部分,一个部分是线程共享区,主要包括堆和方法区,另一部是线程私有区分包括本地方法栈,虚拟机栈和程序计数器.在线程私有部分的三个区域是随着线程生和灭的.栈 ...

  4. 深入分析synchronized的实现原理

    基础概念 synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时可以保证共享变量对内存可见性. Java中每一个对象都可以作为锁,这是synchronize ...

  5. 《Java技术》第三次作业

    (一)学习总结 1.阅读下面程序,分析是否能编译通过?如果不能,说明原因.应该如何修改?程序的运行结果是什么?为什么子类的构造方法在运行之前,必须调用父 类的构造方法?能不能反过来? class Gr ...

  6. 第五次C语言作业

    (一)改错题 输出华氏摄氏温度转换表:输入两个整数lower和upper,输出一张华氏摄氏温度转换表,华氏温度的取值范围是{lower,upper},每次增加2℉.计算公式如下: c = 5×(f-3 ...

  7. Filter,FilterChain,FilterConfig

    实例: package com.zillion.app.filter; import java.io.IOException; import javax.servlet.Filter; import ...

  8. 修改hosts不必重启 立刻生效

    打开命令提示符窗口执行以下命令: 显示DNS缓存内容 ipconfig /displaydns 删除DNS缓存内容 ipconfig /flushdns ps.电脑卡的话,先关机再开机(别直接重启)

  9. Access restriction: The type VerticalTextSpinner is not accessible due to restriction on required library........

    查了下竟然是编译器报错,orz了. Access restriction: 访问限制 on required library: 在依赖库(第三方包) 那就简单了,取消限制就好, eclipse的Win ...

  10. redis分布式锁-SETNX实现

    Redis有一系列的命令,特点是以NX结尾,NX是Not eXists的缩写,如SETNX命令就应该理解为:SET if Not eXists.这系列的命令非常有用,这里讲使用SETNX来实现分布式锁 ...