题意:输入一个序列,输入它排序过程中的一个样子,判断用的是插入排序还是堆排序。并输出下一步。
思路:如果是插入排序的话,那前部分就是有序的,找到第一个无序的位置,从该位置到结尾应该和原本的序列保持一致。否则为堆排序,堆排序的话,那从尾端开始的一部分应该是完全排序好的状态,找到第一个错误的位置,就能找到堆调整的区间,调整一下就好。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 110;
int a[MAX_N], b[MAX_N], tmp[MAX_N];
int n;
bool flag;
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
tmp[i] = a[i];
}
for (int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
}
sort(tmp, tmp+n+1);
int p = 2, t;
flag = true;
while (p <= n && b[p-1] <= b[p]) p++;
for (int i = p; i <= n; i++) {
if (a[i] != b[i]) {
flag = false; break;
}
}
if (flag) {
printf("Insertion Sort\n");
sort(b+1, b+1+p);
for (int i = 1; i <= n; i++) {
if (i > 1) printf(" ");
printf("%d", b[i]);
if (i == n) printf("\n");
}
} else {
printf("Heap Sort\n");
p = n;
while (tmp[p] == b[p]) p--;
swap(b[1], b[p]);
int po = 1;
while (po < p) {
int lc = po * 2, rc = po * 2 + 1;
if (lc < p && rc < p) {
if (b[lc] >= b[rc] && b[lc] > b[po]) {
swap(b[po], b[lc]); po = lc;
} else if (b[rc] > b[lc] && b[rc] > b[po]) {
swap(b[po], b[rc]); po = rc;
}
} else if (lc < p) {
if (b[lc] > b[po]) {
swap(b[po], b[lc]); po = lc;
}
} else break;
}
for (int i = 1; i <= n; i++) {
if (i > 1) printf(" ");
printf("%d", b[i]);
if (i == n) printf("\n");
}
}
return 0;
}