中国大学MOOC-数据结构基础习题集、07-2、Insert or Merge
2015-01-13 21:38
411 查看
题目链接:http://www.patest.cn/contests/mooc-ds/07-2
题目分析:这是一道考察插入排序和归并排序的一道题。题目可能有点难以理解,这里稍加解释一下:
首先,输入的第一行是一个整型数,代表数据的个数。第二行是起始数据,排序从这里开始。第三行是目标(或者叫终止)数据,排序到这里结束。我们知道插入排序和合并排序是有很大不同的,如果是目标数据(我们暂且这么叫)是由插入排序生成的,就输出Insertion Sort;如果是目标数据是由归并排序生成的,就输出Merge Sort。不管是何种输入,都要输出这种排序的“下一步”。注意这里的“下一步”是“一大步”,也就是“一趟”归并排序。
特别说明:
1. 首先推荐一个函数:inplace_merge函数。它的作用和merge函数差不多,只不过是在一个容器中进行归并。
函数参数:inplace_merge(first,mid,last,compare); // 将[first,mid) 和 [mid,last)这两个区间进行归并成一个有序序列。
有了这个可以不用自己写merge了。但是此处博主并没有用到它。这里只是教大家用C++的STL解决实际问题。使用使需要引头文件#include <algorithm>。
如果相对merge类函数有更多了解,不妨阅读:http://www.cppblog.com/zhangyq/archive/2012/02/05/164060.html
2. 刚才说到博主这里没有用到merge类的函数,是因为博主压根没有用“归并排序”。当时博主的最直接的想法就是用sort替代真实的MSort和Merge。所以算是偷懒吧。另外程序中有点了乱,有的地方
3. 插入/合并排序可能出现一趟下来没有改变的情况,要输出有改变的才可以。也就是说你的输出不能和输入的第三行的那串数字相同。这点略坑。可以按照下面的方法测试下自己的代码。
建议测试用例:
测试用例一(这个没什么好说的,肯定都能过,为了与用例二比照):
测试输入:
10
3 1 2 4 5 6 7 9 8 10
1 3 2 4 5 6 7 9 8 10
预期结果:
Insertion Sort
1 2 3 4 5 6 7 9 8 10
测试用例二(重点):
测试输入:
10
3 1 2 4 5 6 7 9 8 10
1 2 3 4 5 6 7 9 8 10
预期结果:
Insertion Sort
1 2 3 4 5 6 7 8 9 10
而不是:
Insertion Sort
1 2 3 4 5 6 7 9 8 10
(和输入第三行一样了,是错的)
[b]代码分析:[/b]
[b] [/b]每个函数前面都有注释,相信大家都能看得懂。
就像前面说的一样,博主只是用到了归并排序的思想,没有真正实现归并排序。想看归并排序的同学,可以看作业07-1,我刚刚更新了归并排序。这里我是借助了sort函数简化代码。这样做有点偷懒,但是却十分方便。
顺便解释一下,为什么在主函数中有a和aa两个数组。这是因为在判断IsInsert中,已经把a数组改变了,所以需要一个备份。就是这样,喵~
AC成果:
![](http://images.cnitblog.com/blog/703960/201501/132134081044905.jpg)
题目分析:这是一道考察插入排序和归并排序的一道题。题目可能有点难以理解,这里稍加解释一下:
首先,输入的第一行是一个整型数,代表数据的个数。第二行是起始数据,排序从这里开始。第三行是目标(或者叫终止)数据,排序到这里结束。我们知道插入排序和合并排序是有很大不同的,如果是目标数据(我们暂且这么叫)是由插入排序生成的,就输出Insertion Sort;如果是目标数据是由归并排序生成的,就输出Merge Sort。不管是何种输入,都要输出这种排序的“下一步”。注意这里的“下一步”是“一大步”,也就是“一趟”归并排序。
特别说明:
1. 首先推荐一个函数:inplace_merge函数。它的作用和merge函数差不多,只不过是在一个容器中进行归并。
函数参数:inplace_merge(first,mid,last,compare); // 将[first,mid) 和 [mid,last)这两个区间进行归并成一个有序序列。
有了这个可以不用自己写merge了。但是此处博主并没有用到它。这里只是教大家用C++的STL解决实际问题。使用使需要引头文件#include <algorithm>。
如果相对merge类函数有更多了解,不妨阅读:http://www.cppblog.com/zhangyq/archive/2012/02/05/164060.html
2. 刚才说到博主这里没有用到merge类的函数,是因为博主压根没有用“归并排序”。当时博主的最直接的想法就是用sort替代真实的MSort和Merge。所以算是偷懒吧。另外程序中有点了乱,有的地方
3. 插入/合并排序可能出现一趟下来没有改变的情况,要输出有改变的才可以。也就是说你的输出不能和输入的第三行的那串数字相同。这点略坑。可以按照下面的方法测试下自己的代码。
建议测试用例:
测试用例一(这个没什么好说的,肯定都能过,为了与用例二比照):
测试输入:
10
3 1 2 4 5 6 7 9 8 10
1 3 2 4 5 6 7 9 8 10
预期结果:
Insertion Sort
1 2 3 4 5 6 7 9 8 10
测试用例二(重点):
测试输入:
10
3 1 2 4 5 6 7 9 8 10
1 2 3 4 5 6 7 9 8 10
预期结果:
Insertion Sort
1 2 3 4 5 6 7 8 9 10
而不是:
Insertion Sort
1 2 3 4 5 6 7 9 8 10
(和输入第三行一样了,是错的)
[b]代码分析:[/b]
[b] [/b]每个函数前面都有注释,相信大家都能看得懂。
就像前面说的一样,博主只是用到了归并排序的思想,没有真正实现归并排序。想看归并排序的同学,可以看作业07-1,我刚刚更新了归并排序。这里我是借助了sort函数简化代码。这样做有点偷懒,但是却十分方便。
顺便解释一下,为什么在主函数中有a和aa两个数组。这是因为在判断IsInsert中,已经把a数组改变了,所以需要一个备份。就是这样,喵~
#include <iostream> #include <algorithm> #define NOTEXIST -1 using namespace std; // 判断两个数组是否相等 bool isEqual(int a[], int b[], int n) { for(int i=0; i<n; i++) if(a[i] != b[i]) return false; return true; } // 进行插入排序的移动元素操作 int moveElement(int i, int a[]) { int tmp = a[i]; int j; for(j=i; j>0 && a[j-1] > tmp; j--) a[j] = a[j-1]; a[j] = tmp; return j; } // 判断是不是插入排序 int isInsertSort(int a[], int b[], int n) { for(int i=0; i<n; i++) { moveElement(i, a); if(isEqual(a, b, n) == true) return i; } return NOTEXIST; } // 非递归算法 bool MSort( int A[], int B[], int N ) { int step = 1; bool myFlag = false; while(step < N) { step *= 2; for(int i=0; i<N; i=i+step) { int first = i; int last = first + step; if(last >= N) last = N; sort(A+first, A+last); } if(myFlag == true) { // 如果已经成功,走完了归并排序之后直接返回即可!注意此if语句应该位于下一个if语句之前!! if(isEqual(A, B, N) == false) return true; } if(isEqual(A, B, N) == true) { // 如果发现和目标数据相同,则置myFlag标识为true,代表已经成功,只需要再走一次归并排序即可! myFlag = true; } } return false; } // 输出数组内的元素 void outputElement(int x[], int n) { for(int i=0; i<n; i++) { if(i != n-1) cout << x[i] << " "; else cout << x[i]; } cout << endl; } int main() { int n; cin >> n; int *a = new int ; int *aa = new int ; for(int i=0; i<n; i++) { cin >> a[i]; aa[i] = a[i]; } int *b = new int ; for(int j=0; j<n; j++) cin >> b[j]; int IS = isInsertSort(a, b, n); if(IS != NOTEXIST) { cout << "Insertion Sort" << endl; while(isEqual(a, b, n) == true) { IS = moveElement(IS+1, a); } outputElement(a, n); } else { cout << "Merge Sort" << endl; MSort(aa, b, n); outputElement(aa, n); } return 0; }
AC成果:
![](http://images.cnitblog.com/blog/703960/201501/132134081044905.jpg)
相关文章推荐
- 中国大学MOOC-数据结构基础习题集、07-2、Insert or Merge
- 中国大学MOOC-数据结构基础习题集、07-1、排序
- 中国大学MOOC-数据结构基础习题集、02-3、求前缀表达式的值
- 中国大学MOOC-数据结构基础习题集、04-1、Root of AVL Tree
- 中国大学MOOC-数据结构基础习题集、04-2、File Transfer
- 中国大学MOOC-数据结构基础习题集、03-1、二分法求多项式单根
- 中国大学MOOC-数据结构基础习题集、06-3、公路村村通
- 中国大学MOOC-数据结构基础习题集、08-1、Talent and Virtue
- 中国大学MOOC-数据结构基础习题集、06-5、关键活动
- 中国大学MOOC-数据结构基础习题集、09-3、Hashing - Hard Version
- 中国大学MOOC-数据结构基础习题集、03-2、List Leaves
- 中国大学MOOC-数据结构基础习题集、06-2、旅游规划
- 中国大学MOOC-数据结构基础习题集、06-1、Saving James Bond - Hard Version
- 中国大学MOOC-数据结构基础习题集、08-2、The World's Richest
- 中国大学MOOC-陈越、何钦铭-数据结构基础习题集 00-自测3-数组元素循环右移问题 (20)
- 中国大学MOOC-数据结构基础习题集、03-3、Tree Traversals Again
- 中国大学MOOC-数据结构基础习题集、04-3、Huffman Codes
- 中国大学MOOC-数据结构基础习题集、05-3、六度空间
- 中国大学MOOC-数据结构基础习题集、09-1、Hashing
- 中国大学MOOC-数据结构基础习题集、08-3、Sort with Swap(0,*)