题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805368847187968
题目大意
给你长度为n的数组a和b,其中数组a是原数组,b是插入排序或堆排序过程中的某一步得到的数组,让你判断是哪种排序方法,以及下一步得到的数组是什么。
分析
如果是插入排序,那么b数组前半部分一定是有序的,后半部分与a数组相同,否则就是堆排序。如果是堆排序,那么当前在序列中,也分为两部分,后半部分一定比b[1]大,前半部分b[1]是最大的元素,那么我们就可以从后往前找第一个比b[1]小的,假设位置为x,交换b[1]与b[x],然后再把1--x-1按照堆排序的方法操作一遍就可以了。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, a[110], b[110];
void solve(int l, int r) {
int x = 1;
while(x <= r) {
int j = x << 1;
if(j > r) break;
if(j + 1 <= r && b[j + 1] > b[j])
j++;
if(b[j] <= b[x]) break;
swap(b[x], b[j]);
x = j;
}
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= n; i++)
scanf("%d", &b[i]);
int x = 2;
while(x <= n && b[x] >= b[x - 1])
x++;
int id = x;
while(x <= n && a[x] == b[x])
x++;
if(x == n + 1) {
printf("Insertion Sort\n");
sort(b + 1, b + id + 1);
for(int i = 1; i <= n; i++)
printf("%d%s", b[i], i == n ? "\n" : " ");
} else {
printf("Heap Sort\n");
x = n;
while(x > 2 && b[x] >= b[1])
x--;
swap(b[1], b[x]);
solve(1, x - 1);
for(int k = 1; k <= n; k++)
printf("%d%s", b[k], k == n ? "\n" : " ");
}
return 0;
}