PAT Advanced 1089 Insert or Merge (25) [two pointers]
题目
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
- 如果是插入排序,对[0,i+1]的数字进行排序就是下一轮插入排序的结果
- 如果是归并排序,从原始数组使用非递归归并代码执行归并过程,并在每一轮判断排序结果是否已经是题目中已知的数组b,若是,则再进行一轮归并即可得出结果
思路 02
- 对原始数组分别进行插入排序和归并排序,在每一轮结束后,判断排序结果是否已经是题目中已知的数组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]的更多相关文章
- PAT甲级:1089 Insert or Merge (25分)
PAT甲级:1089 Insert or Merge (25分) 题干 According to Wikipedia: Insertion sort iterates, consuming one i ...
- PAT甲级1089. Insert or Merge
PAT甲级1089. Insert or Merge 题意: 根据维基百科: 插入排序迭代,消耗一个输入元素每次重复,并增加排序的输出列表.每次迭代,插入排序从输入数据中删除一个元素,在排序列表中找到 ...
- PAT (Advanced Level) 1089. Insert or Merge (25)
简单题.模拟一下即可. #include<cstdio> #include<cstring> #include<cmath> #include<vector& ...
- PAT 1089. Insert or Merge (25)
According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...
- 【PAT甲级】1089 Insert or Merge (25 分)(插入排序和归并排序)
题意: 输入一个正整数N(<=100),接着输入两行N个整数,第一行表示初始序列,第二行表示经过一定程度的排序后的序列.输出这个序列是由插入排序或者归并排序得到的,并且下一行输出经过再一次排序操 ...
- 1089. Insert or Merge (25)
题目如下: According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, ...
- 1089. Insert or Merge (25)-判断插入排序还是归并排序
判断插入排序很好判断,不是的话那就是归并排序了. 由于归并排序区间是2.4.8开始递增的,所以要判断给出的归并排序执行到哪一步,就要k从2开始枚举. 然后再对每个子区间进行一下sort即可. #inc ...
- 1089 Insert or Merge (25 分)
According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...
- 1089 Insert or Merge (25分)
According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...
随机推荐
- 九十、SAP中ALV事件之四,事件子例程的参数
一.我们按照之前SAP说明里面的文字,定义好相关内容 二.上图代码对应的文档错了,重现截图一下 三.这3个子例程是不需要写调用语句PERFORM的,在SAP内部已经写好了.程序会自动根据名字找到需要调 ...
- python连接 ssh
import paramiko # private = paramiko.RSAKey.from_private_key() 秘钥 trans = paramiko.Transport((" ...
- Day 19:Properties配置文件类、打印流(printStream) 、 编码与解码
Properties(配置文件类): 主要用于生产配置文件与读取配置文件的信息. Properties要注意的细节: 1. 如果配置文件的信息一旦使用了中文,那么在使用store方法生成配置文件的时 ...
- ES6中字符串的新增方法梳理
1.String.fromCodePoint(); String,fromCodePoint()方法可以认为是对String.fromCharCode()方法的扩展,这两个方法的共同点在于都是用于Un ...
- P1012 数字分类
转跳点:
- 【LeetCode】组合总和
[问题]给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制 ...
- Spring注解——@Transactional
@Transactional 用于service实现类,声明这个service所有方法需要事务管理.每一个业务方法开始时都会打开一个事务.(未完待续)
- k8s安装helm
1.客户端安装 A.直接在github上下载二进制文件进行解压,下载地址:https://github.com/kubernetes/helm/releases B.将解压出来的二进制文件helm 拷 ...
- It can be a face application using SeetaFace and Qt.
之前编译了一下SeetaFace的库,用于人脸检测.特征点定位和人脸识别的功能,然后昨天就用Qt写了一个软件用于实现. 工程的文件还是比较简单的,一个界面类和一个SeetaFace的线程类而已.这里主 ...
- 使用super调用被子类覆盖的父类方法
1.没有super方法 /* * 子类方法覆盖父类方法,用super方法可以调用父类被覆盖的方法 */ class fruit{ public fruit() { System.out.println ...