PAT A1089 Insert or Merge (25 point(s))

8 篇文章 0 订阅

题目大意:

  • 题目给出两个数组a1和a2,a1是初始数组,a2是经过若干次插入排序或者归并排序后得到的数组。让你判断a2是经过哪种排序得到的,并且输出下一趟排序后的结果。

注意:

  • 如果对插入排序和归并排序掌握得不好,这题就要GG。
  • 插入排序的特点是:第n趟排序结束后,前 i 个元素有序,后 n-i 个元素保持不变。
  • 归并排序(2路)的特点是:第i次排序结束后,每n/(2^i)个子列内部是有序的
  • 如果判断是插入排序,下次排序结果好得,sort+1即可
  • 如果判断是归并排序,可直接用归并排序的非递归算法。先要根据每次归并后的结果与a对比,得出当前step;然后就是常规算法。(注意:因为本题数据范围较小,故不需要真的“归并”,每次子列内部用sort即可。

代码:

#include<cstdio>
#include<algorithm>
#include<iostream>

using namespace std;
const int maxn = 110;
int n;
int temp[maxn] = {0}, b[maxn], a[maxn];//a:初始 b:目标

int isSame(int temp[], int b[]) //判断两个数组是否相等
{
    for(int i = 0; i < n; i++)
        if(b[i] != temp[i])
            return 0;
    return 1;
}

void toPrint(int temp[])    //打印数组
{
    for(int i = 0; i < n; i++)
    {
        cout << temp[i];
        if(i < n - 1)
            cout << " ";
    }
}

int main()
{
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        cin >> a[i];
        temp[i] = a[i];
    }

    for(int i = 0; i < n; i++)
        cin >> b[i];

    //判断是否是insertSort
    int i = 0, j = 0;
    for(i = 0; i < n - 1 && b[i] <= b[i + 1]; i++); //i=左边起最后一个有序的数字
    //cout << "i=" << i << endl;
    //从i+1开始到n-1为止,若与a1相同,则是insert排序
    for(j = i + 1; j < n && a[j] == b[j]; j++);
    if(j == n)
    {
        cout << "Insertion Sort" << endl;
        //insertsort
        sort(temp, temp + i + 2);
        toPrint(temp);
        return 0;
    }
    else
    {
        cout << "Merge Sort" << endl;
        int step = 2;
        bool flag = false;
        for(step = 2; step / 2 < n; step *= 2)
        {
            if(isSame(temp, b))
                flag = true;
            //本次归并
            for(int i = 0; i < n; i += step)
            {

                sort(temp + i, temp + min( i + step, n));
                //cout<<"i="<<i<<" "<<"step="<<step<<" ";
                //toPrint(temp);
                //cout<<endl;
            }
            if(flag)
            {
                toPrint(temp);
                return 0;
            }
        }                                                                                                                    ;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值