#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
using namespace std;
//A1098
const int maxn=105;//一定要比100大
int n;
int origin[maxn],temp[maxn],result[maxn];
void printArray(int a[]){
for(int i=1;i<=n;i++){
if(i!=1)printf(" ");
printf("%d",a[i]);
}
}
bool isSame(int a[],int b[]){
for(int i=1;i<=n;i++){
if(a[i]!=b[i])return false;
}
return true;
}
bool insertSort(){
bool flag=false;//判断是否是初始序列
//从2开始为未排序数组
for(int i=2;i<=n;i++){
if(i!=2&&isSame(temp,result)){
flag=true;
}
sort(temp+1,temp+i+1);//使用sort进行插入排序
if(flag){
return true;//是插入排序
}
}
return false;
}
//
void downAdjust(int low,int high){
int i=low;
int j=low*2;//左节点的下标
while(j<=high){
//右孩子存在且比左孩子权值大的时候进行节点的更新
if(j+1<=high&&temp[j+1]>temp[j]){
j=j+1;
}
//孩子节点的值比root值大则交换
if(temp[j]>temp[i]){
swap(temp[j],temp[i]);
i=j;
j=2*i;
}else{
break;
}
}
}
void createHeap(){
for(int i=n/2;i>=1;i--){
downAdjust(i,n);
}
}
void heapSort(){
bool flag=false;
createHeap();
for(int i=n;i>1;i--){
if(i!=n&&isSame(temp,result)){
flag=true;
}
swap(temp[i],temp[1]);//将根节点和最后一个节点进行交换
downAdjust(1,i-1);
if(flag){
printArray(temp);
return;
}
}
}
int main()
{
scanf("%d",&n);
//完全二叉树的root最好下标从1开始
//堆就是个完全二叉树
for(int i=1;i<=n;i++){
scanf("%d",&origin[i]);
temp[i]=origin[i];
}
for(int i=1;i<=n;i++){
scanf("%d",&result[i]);
}
if(insertSort()==true){
printf("Insertion Sort\n");
printArray(temp);
}else{
printf("Heap Sort\n");
for(int i=1;i<=n;i++){
temp[i]=origin[i];
}
heapSort();
}
return 0;
}
#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
using namespace std;
//A1098
const int maxn=105;
int n;
int origin[maxn],temp[maxn],result[maxn];
void printArray(int a[]){
for(int i=1;i<=n;i++){
if(i!=1)printf(" ");
printf("%d",a[i]);
}
}
void downAdjust(int low,int high){
int i=low;
int j=low*2;//左节点的下标
while(j<=high){
//右孩子存在且比左孩子权值大的时候进行节点的更新
if(j+1<=high&&result[j+1]>result[j]){
j=j+1;
}
//孩子节点的值比root值大则交换
if(result[j]>result[i]){
swap(result[j],result[i]);
i=j;
j=2*i;
}else{
break;
}
}
}
int main()
{
scanf("%d",&n);
//完全二叉树的root最好下标从1开始
//堆就是个完全二叉树
for(int i=1;i<=n;i++){
scanf("%d",&origin[i]);
temp[i]=origin[i];
}
for(int i=1;i<=n;i++){
scanf("%d",&result[i]);
}
int p=2;
while(p<=n&&result[p-1]<=result[p]){
p++;
}
int index=p;
int flag=1;//是否是插入排序
for(int i=index;i<=n;i++){
if(result[i]!=origin[i]){
flag=0;//不是插入排序
}
}
if(flag==1){
printf("Insertion Sort\n");
sort(result+1,result+index+1);
printArray(result);
}else{
printf("Heap Sort\n");
int pos=n;
//找到第一个比result[i]小的数:交换并且向下调整
while(pos>2&&result[pos]>result[1]){
pos--;
}
int index1=pos;
swap(result[1],result[index1]);
downAdjust(1,index1-1);
printArray(result);
}
return 0;
}