1035. 插入与归并(25)
时间限制
200 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
根据维基百科的定义:
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
归并排序进行如下迭代操作:首先将原始序列看成N个只包含1个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下1个有序的序列。
现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?
输入格式:
输入在第一行给出正整数N (<=100);随后一行给出原始序列的N个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。
输出格式:
首先在第1行中输出“Insertion Sort”表示插入排序、或“Merge Sort”表示归并排序;然后在第2行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行末不得有多余空格。
输入样例1:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
输出样例1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
输入样例2:
10
3 1 2 8 7 5 9 4 0 6
1 3 2 8 5 7 4 9 0 6
输出样例2:
Merge Sort
1 2 3 8 4 5 7 9 0 6
做这道题的时候,我先是自己写了一遍插入排序和归并排序,umm,事实上归并排序的代码并不是很熟,所以有在网上参考资料,偶然发现这个题可以不用自己写,用sort取模拟就好了。于是愉快地换成了现在这份代码,这里有碰到几个坑,记录下:
1. 因为vs对stl良好的支持,所以我一直用vs进行书写代码和调试,vs有个问题是声明一个数组必须要求大小是一个常量而不是变量,这就意味着不能先用一个变量读入长度再声明数组,因此我一直用vector代替传统数组。这里要注意的是vector作为函数参数的时候,和传入数组名不同,vector默认传的是拷贝,要改变其元素顺序的话,必须传引用。
2. 其次,c++没有or关键字,所以vs中or可以直接作为用户变量名,但g++这些编译器都把or作为保留字,无法编译通过,很迷
3. sort的两个参数是算法是不一样的,比如说有vector<int> emm(10)
,如果我们用sort(emm.begin()+5, emm.begin()+9)
,那么排序的是emm[5]到emm[8],而不是5到9,这是个大坑
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int ismatch(vector<int> &ori, vector<int> &in){
int j = 0;
for (; j < ori.size(); j++)
if (ori[j] != in[j])
break;
if (j == ori.size())
return 1;
else return 0;
}
int main(){
int ismatch(vector<int> &ori, vector<int> &in);
int n;
cin >> n;
/* if (n == 1){
cin >> n;
cin.get();
cin.get();
cout << "Insertion Sort" << endl;
cout << n;
return 0;
}*/
vector<int> ori(n, 0);
vector<int> in(n, 0);
for (int i = 0; i < n; i++)
cin >> ori[i];
for (int i = 0; i < n; i++)
cin >> in[i];
vector<int> arr(n, 0);
arr = ori;
//insert sort
for (int i = 2; i < n; i++){
sort(ori.begin(), ori.begin() + i);
//check
if (ismatch(ori, in)){
cout << "Insertion Sort" << endl;
sort(ori.begin(), ori.begin()+i+1);
for (int k = 0; k < n; k++){
cout << ori[k];
if (k != n - 1)
cout << ' ';
}
return 0;
}
}
//merge sort
ori = arr;
int m = 0;
float ml = log(n);
if ((ml - (int)ml) != 0)
m = (int)ml + 1;
else m = (int)ml;
int step = 2;
for (int i = 0; i < m; i++, step *= 2){
for (int j = 0;; j += step){
if ((j + step) < ori.size())
sort(ori.begin()+j, ori.begin()+j+step);
else{
sort(ori.begin()+j, ori.end());
break;
}
}
//check
int k = 0;
for (; k < n; k++)
if (ori[k] != in[k])
break;
if (k == n){
cout << "Merge Sort" << endl;
step *= 2;
for (int e = 0;; e += step){
if ((e + step) < ori.size())
sort(ori.begin() + e, ori.begin() + e + step);
else{
sort(ori.begin() + e, ori.end());
break;
}
}
for (int o = 0; o < n; o++){
cout << ori[o];
if (o != n - 1)
cout << ' ';
}
return 0;
}
}
return 0;
}