PAT basic-level 1035 插入与归并 笔记

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值