7-16 插入排序还是归并排序 (25 分)
题目链接:https://pintia.cn/problem-sets/1110537862649819136/problems/1110537981575114767
题目大意:
根据维基百科的定义:
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
归并排序进行如下迭代操作:首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。
现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?
输入格式:
输入在第一行给出正整数 N (≤100);随后一行给出原始序列的 N 个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。
输出格式:
首先在第 1 行中输出Insertion Sort
表示插入排序、或Merge Sort
表示归并排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格。
具体思路:
对于判断插入排序的时候,我们判断到什么位置不再是保持递增的,然后在判断一下这个点后面的和原数组是不是相同的,这样就能理解为前面的部分已经排好了,但是后面的并没有来得及排。
然后对于归并排序的时候,这个排序的思想类似于分治的思想,把每一小段排好,然后再汇总起来去排好。一开始的时候是两个两个的,然后再就是4个,类似这种情况。对于这个题,我们先从原数组进行操作,看一下到b数组的Step是多少,然后再Step*2,再排一下序,就是再进行一步的感觉,直接输出就可以了。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 # define inf 0x3f3f3f3f 5 const int maxn = 2e5+100; 6 int a[maxn]; 7 int b[maxn]; 8 int n; 9 bool judge(int t){ 10 for(int i=0;i<n;i++){ 11 if(a[i]!=b[i])return false; 12 } 13 return true; 14 } 15 int main(){ 16 scanf("%d",&n); 17 for(int i=0;i<n;i++){ 18 scanf("%d",&a[i]); 19 } 20 for(int j=0;j<n;j++){ 21 scanf("%d",&b[j]); 22 } 23 int i,j; 24 for( i=1;i<n&&b[i]>=b[i-1];i++); 25 for( j=i;j<n&&(b[j]==a[j]);j++); 26 if(j==n){ 27 printf("Insertion Sort\n"); 28 sort(b,b+i+1,n)); 29 for(int i=0;i<n;i++){ 30 if(i==0)printf("%d",b[i]); 31 else printf(" %d",b[i]); 32 } 33 printf("\n"); 34 return 0; 35 } 36 printf("Merge Sort\n"); 37 i=2; 38 for(;!judge(i);i+=i){ 39 for(int j=0;j<n;j+=i)sort(a+j,a+min(j+i,n)); 40 } 41 for(int j=0;j<n;j+=i)sort(a+j,a+min(j+i,n)); 42 for(int i=0;i<n;i++){ 43 if(i==0)printf("%d",a[i]); 44 else printf(" %d",a[i]); 45 } 46 printf("\n"); 47 return 0; 48 }