PAT乙级1035插入与归并

链接: https://www.nowcoder.com/questionTerminal/11ab86465a7449d3ac0181ff134e9369
来源:牛客网

根据维基百科的定义:

插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确
的位置。如此迭代直到全部元素有序。

归并排序进行如下迭代操作:首先将原始序列看成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

输出

Insertion Sort

1 2 3 5 7 8 9 4 6 0

此题容易先入为主,误以为该题需要自己去模拟插入与归并排序的过程。

其实只要考虑插入与归并两种排序有区别,插入排序前一部分有序,而后半部分与原序列相同。只需循环一次找出第二个序列有序部分与无序部分的分割点并将割点之后的数与原数列对比即可。若为插入只需使用sort多排一位;

而若为归并排序则需要自己使用sort模拟归并过程,并在给出数列的基础上多归并一次。

#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
bool cmp(int a,int b)
{
    return a<b;
}
int main()
{
    int i,j,k,m,n;
    cin>>n;
    vector <int> a,b;
    for(i=0;i<n;i++)
    {
        cin>>k;//vector容器无法直接输入
        a.push_back(k);//vector容器的数值写入方式
    }
    for(j=0;j<n;j++)
    {
        cin>>m;
        b.push_back(m);
    }
    int pan=-1;
    bool flag=false;
    for(i=0;i<n-1;i++)
    {
        if(b[i]>b[i+1])
        {
            pan=i+1;
            break;
        }
        //cout<<b[i]<<" "<<b[i+1]<<endl;
    }
    for(i=pan;i<n;i++)
        if(a[i]!=b[i])
    {
        flag=true;
        break;
    }
    if(!flag)
    {
        sort(a.begin(),a.begin()+(pan+1),cmp);//进行下次排序
        cout<<"Insertion Sort"<<endl;
        for(i=0;i<n-1;i++)
            cout<<a[i]<<" ";
        cout<<a[i];
    }
    else
    {
        cout<<"Merge Sort"<<endl;
        k=1;
        flag=true;
        while(flag)
        {
            flag=false;
            if(!equal(a.begin(),a.end(),b.begin()))//只要与b不想等就要一直进行排序
                flag=true;
            k*=2;
            for(i=0;i<n/k;i++)
            {
                sort(a.begin()+i*k,a.begin()+(i+1)*k);//模拟归并排序
            }
            sort(a.begin()+k*(n/k),a.end());//对剩余n%k部分进行排序
        }
        for(i=0;i<n-1;i++)
            cout<<a[i]<<" ";
        cout<<a[i];
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值