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 }

 

posted @ 2019-03-28 17:01  Let_Life_Stop  阅读(2090)  评论(0编辑  收藏  举报