1035 插入与归并(C语言)

设计思路:
  1. 插入排序的判断:
    (开头一部分一定有序)&&(无序部分与原序列一致)

  2. 归并排序的判断:
    排除法

  3. 插入排序迭代一次:
    从断点迭代一次即可

  4. 归并排序迭代一次:

  • 方法一:对原序列归并排序,匹配到题目第 2 个序列后,再迭代一次
  • 方法二:关键在于确定归并段长度,然后列用归并段长度迭代一次第 2 个序列。
寻找归并段长度:
1.设初始长度 L = 2(长度为 1 无意义)
2.如图:(每个 L 范围内均有序)&&(每 2L 范围内均有序),则 L = 2L,否则终止。最终找到归并段长度 L。
| L | L | L | L | L | L | L | L |
|   2L  |   2L  |   2L  |   2L  |
代码实现:
int bool = 0;
for(L = 2; L <= N; L *= 2L){
            for(i = L; i < N; i += 2*L){
                if(tmp[i - 1] > tmp[ i ]){
                    bool = 1;
                    break;
                }
            }
            if(bool){
                k = L;
                break;
            }
}
感谢 Ionizing 大佬的博客,详细展示了各种错误姿势:
https://ionizing.science/2017/06/22/PAT%E9%A2%98%E8%A7%A3-B-1035/
最初想到像插入排序一样从头开始寻找最长有序子序列,来确定 L 值,此错误姿势破解如下,

10
2 1 8 3 7 5 9 4 0 6
1 2 3 8 5 7 4 9 0 6

我们无法从 1 3 2 8 是最长前置有序子列就判断出归并段的长度为 4,正确答案应该是 2
编译器:C (gcc)
#include <stdio.h>

int isinsertion(int n, int num[], int half[]);
int nextmerge(int n, int num[], int half[]);

int comp(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}

int main()
{
    int n, num[100], half[100];
    int i;
    scanf("%d", &n);
    for(i = 0; i < n; i++) scanf("%d", &num[i]);
    for(i = 0; i < n; i++) scanf("%d", &half[i]);

    if(isinsertion(n, num, half)) nextmerge(n, num, half);

    for(i = 0; i < n; i++){
        printf("%d%c", num[i], i == n - 1 ? '\n' : ' ');
    }
    return 0;
}

int isinsertion(int n, int num[], int half[])
{
    int i, lenth;
    for(i = 0; i < n - 1 && half[i] <= half[i + 1]; i++){
        continue;
    }
    for(i++, lenth = i; i < n && half[i] == num[i]; i++){
        continue;
    }
    if(i < n)
        return 1;
    printf("Insertion Sort\n");
    lenth++;
    qsort(num, lenth, sizeof(int), comp);
    return 0;
}

int nextmerge(int n, int num[], int half[])
{
    int i, j, lenth;
    printf("Merge Sort\n");
    for(lenth = 1, i = 0; i < n && lenth <= n; lenth *=2){
        for(i = 0; i < n && num[i] == half[i]; i++) ;
        for(j = 0; j < n / lenth; j++){
            qsort(num + j * lenth, lenth, sizeof(int), comp);
        }
        qsort(num + j * lenth, n % lenth, sizeof(int), comp);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/huaxuewan/article/details/88316330