1089 Insert or Merge (25 分)

题意

给出一个初始序列,可以将它使用插入排序或归并排序进行排序。现在给出一个序列,问它是由插入排序还是归并排序产生的,并输出下一步将会产生的序列。

思路

本题需要直接模拟插入排序和归并排序的每一步过程,其中归并排序使用非递归形式会更方便一些。整体做法为:先进行插入排序,如果执行过程中发现与给定序列吻合,那么说明是插入排序,计算出下一步的序列后结束算法;如果不是插入排序,那么一定是归并排序,模拟归并排序的过程,如果执行过程中发现与给定序列吻合,那么计算出下一步的序列后结束算法。

注意点

  1. 由于数据范围较小,因此归并排序中可以不写合并函数,而直接用sort代替。
  2. 注意初始序列和目标序列相等的情况。
const int N=110;
int a[N];
int b[N];
int temp[N];
int n;

bool isSame()
{
    for(int i=0;i<n;i++)
        if(a[i] != b[i])
            return false;
    return true;
}

bool insertSort()
{
    bool ok=false;
    for(int i=1;i<n;i++)
    {
        if(isSame() && i != 1) ok=true;
        int t=a[i];
        int j=i;
        while(j && a[j-1] > t)
        {
            a[j]=a[j-1];
            j--;
        }
        a[j]=t;

        if(ok) return true;
    }
    return false;
}

void mergeSort()
{
    memcpy(a,temp,sizeof temp);
    bool ok=false;
    for(int len=2;len/2<=n;len<<=1)
    {
        if(isSame()) ok=true;
        for(int i=0;i<n;i+=len)
            sort(a+i,a+min(i+len,n));

        if(ok) break;
    }
}

int main()
{
    cin>>n;

    for(int i=0;i<n;i++) cin>>a[i];
    memcpy(temp,a,sizeof a);

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

    if(insertSort())
    {
        puts("Insertion Sort");
    }
    else
    {
        puts("Merge Sort");
        mergeSort();
    }

    for(int i=0;i<n;i++)
        if(i) cout<<' '<<a[i];
        else cout<<a[i];
    cout<<endl;
    //system("pause");
    return 0;
}
posted @ 2021-02-19 23:21  Dazzling!  阅读(46)  评论(0编辑  收藏  举报