题目大意:
- 题目给出两个数组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;
}
} ;
}
}