1035 插入与归并 (25 point(s))

题目

根据维基百科的定义:

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

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

我的代码

在这里插入图片描述

又臭又长 排序写的比较慢 且归并排序的手写迭代写不出来 有些点过不去

#include<iostream>
#include<algorithm>
using namespace std;
bool m;
void swap(int&a,int&b)
{
    int temp=a;
    a=b;
    b=temp;
}
bool judge(int a[],int n,int b[])
{
    for(int i=0;i<n;i++)
    {
        if(a[i]!=b[i]) return false;
    }
    return true;
}
void printSorted(int a[],int n)
{
    cout<<a[0];
    for(int i=1;i<n;i++)
    {
        cout<<" "<<a[i];
    }
    cout<<endl;
}
void MergeSort(int a[],int n,int b[])
{
    
    
}
void InsertSort(int a[],int n,int b[])
{
    for(int i=1;i<n;i++)
    {
        for(int j=i;j>0;j--)
        {
            if(a[j]<a[j-1]) swap(a[j],a[j-1]);
        }
        if(judge(a,n,b))
        {
            i++;
            for(int j=i;j>0;j--)
        {
            if(a[j]<a[j-1]) swap(a[j],a[j-1]);
        }
            cout<<"Insertion Sort"<<endl;
            printSorted(a,n);
            m=1;
            return;
        }
    }
    m=0;
}

int main()
{
    //其实就是用归并排序和插入排序都走一遍 如果匹配就输出 另一个就break;
    int n;cin>>n;
    int orignal[n];for(int i=0;i<n;i++) cin>>orignal[i];
    int goal[n];for(int i=0;i<n;i++) cin>>goal[i];
    if(m==1) 
    {
        InsertSort(orignal,n,goal);
    }
    else
    {
        int i,j;
        cout << "Merge Sort" << endl;
    int k = 1, flag = 1;
while(flag) 
{
    flag = 0;
    for (i = 0; i < n; i++)
    {
        if (orignal[i] != goal[i])
        flag = 1;
    }
    k = k * 2;
    for (i = 0; i < n / k; i++)
    sort(orignal + i * k, orignal + (i + 1) * k);
    sort(orignal + n / k * k, orignal + n);
}
        for (j = 0; j < n; j++) {
if (j != 0) printf(" ");
printf("%d", orignal[j]);
    }
    }
}

正确代码

大神的思路都放代码里了 啃起来比较直观

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    //抄了半天 竟然跑不通 难受
    int n,a[100],b[100],i,j;
    cin>>n;
    for(i = 0; i < n; i++) cin >> a[i];
    for(i = 0; i < n; i++) cin >> b[i];
    
    for(i=0;i<n-1&&b[i]<=b[i+1];i++); //判断升序的断点
    for(j=i+1;a[j]==b[j]&&j<n;j++); //判断是否为插入排序剩余的工作
     if(j==n)//如果一致 则为插入排序
     {
         cout<<"Insertion Sort"<<endl;
         sort(a,a+i+1+1);//直接用简便  还是习惯手撕排序 下一轮排序+1
     }
    else
    {
        cout<<"Merge Sort"<<endl;
        int k=1,flag=1;
        while(flag)
        {
            flag=0;
            for(i=0;i<n;i++)
            {
                if(a[i]!=b[i]) 
                    flag=1; //如果没找到排序中相同的那一步骤则继续循环
            }
            //如果相等 下面就是再排一轮
            k=k*2;//2 4 8 从两个开始排序
            for(i=0;i<n/k;i++) //每k个为一组 
            {
                sort(a+i*k,a+(i+1)*k);//0-2 2-4 4...8-10 区间问题 右-左 被排序的个数(包括左边端点)
                                      // 01 23 45 67 89
            }
            sort(a+(n/k)*k,a+n); //再排一轮? 排剩余没有凑够k个的
        }
    }
    for(j=0;j<n;j++)
    {
        if(j!=0) cout<<" ";
        cout<<a[j];
    }
}

原文地址:https://www.cnblogs.com/most-silence/p/15495362.html