A1089 Insert or Merge (25 分| two pointers,附详细注释,逻辑分析)

写在前面

  • 思路分析
    • 现给定原始序列和由某排序算法产生的中间序列,请判断该算法是插入算法还是归并算法。
    • 实现分析:
      • 先将i指向中间序列中满足从左到右是从小到大顺序的最后1个下标,再将j指向从i+1开始,第1个不满足a[j] == b[j]的下标
        • 如果j顺利到达下标n,说明是插入排序,再下1次的序列是sort(a, a+i+2)
        • 否则是归并排序
          • i从0到n/k,每次1段段得sort(a + i * k, a + (i + 1) * k);
          • 剩余部分的sort(a + n / k * k, a + n);
          • 直到有1次发现a的顺序和b的顺序相同,则再归并1次,然后退出循环
  • 题目基础,学习ing

测试用例

  • input:
    10
    3 1 2 8 7 5 9 4 6 0
    1 2 3 7 8 5 9 4 6 0
    output:
    Insertion Sort
    1 2 3 5 7 8 9 4 6 0
    
    input:
    10
    3 1 2 8 7 5 9 4 0 6
    1 3 2 8 5 7 4 9 0 6
    output:
    Merge Sort
    1 2 3 8 4 5 7 9 0 6
    

ac代码

  • #include 
    #include 
    using namespace std;
    int main()
    {
        int n, a[100], b[100], i, j;
        cin >> n;
        for (int i = 0; i < n; i++)
            cin >> a[i];
        for (int 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 + 2);
        }
        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;
                for (i = 0; i < n / k; i++)
                    sort(a + i * k, a + (i + 1) * k);
                sort(a + n / k * k, a + n);
            }
        }
        for (j = 0; j < n; j++)
        {
            if (j != 0) printf(" ");
            printf("%d", a[j]);
        }
        return 0;
    }
    

你可能感兴趣的:(A1089,Insert,or,Merge,two,pointers,算法比赛相关,PAT(甲级))