题目
根据维基百科的定义:
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
归并排序进行如下迭代操作:首先将原始序列看成 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];
}
}