1098. Insertion or Heap Sort (25)堆排序模拟
题目
https://pintia.cn/problem-sets/994805342720868352/problems/994805368847187968
题意
给出n和n个数的序列a和b,a为原始序列,b为排序其中的一个步骤,问b是a经过了堆排序还是插入排序的,并且输出它的下一步
Sample Input 1:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
Sample Output 1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
Sample Input 2:
10
3 1 2 8 7 5 9 4 6 0
6 4 5 1 0 3 2 7 8 9
Sample Output 2:
Heap Sort
5 4 3 1 0 2 6 7 8 9
解法
若是插入排序,序列前面有序,后面相同
否则是堆排序
是否考虑特殊情况:经过一趟插入排序后,序列没有变化
比如:
8 7 1 2 3 9 5 6
1 2 3 7 8 9 5 6
这个9算不算排过了呢??题目貌似算排过了
code
/***************************
Hello World!
***************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int a[105];
int b[103];
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
//为什么要先判断左(正序)后右(相等),才能决定是否是insert
/**
8 7 1 2 3 9 5 6
1 2 3 7 8 9 5 6
这个9算不算排过了呢
**/
/** 按下面的写法(也就是从右向左判断),9不算排过 **/
// int p=n;
// while(p>=1 && a[p]==b[p]) p--;
// //判断1-p是否有序
// int index=p+1;
// while(p>=2 && b[p-1]<=b[p]) p--;
/** 按下面的写法(也就是从左向右判断),9算排过 **/
int p=2;
while(p<=n && b[p-1]<=b[p]) p++;
int index=p;
while(p<=n && b[p]==a[p]) p++;
//第一趟插入序列不变的
if(p>n)//是插入
{
cout<<"Insertion Sort"<<endl;
sort(b+1,b+index+1);
for(int i=1;i<n;i++) cout<<b[i]<<" ";
cout<<b[n]<<endl;
}
else//堆排序
{
cout<<"Heap Sort"<<endl;
int fin;
for(int i=n;i>=1;--i)
{
if(b[i]<=b[1]) {
fin=i; break;
}
}
swap(b[1],b[fin]);
fin--;
int p=1;
while(p<=fin/2)
{
int j;
if(2*p+1<=fin) {
j=b[2*p]>b[2*p+1]?2*p:2*p+1;
}
else {
j=2*p;
}
if(b[j]>b[p]) {
swap(b[j],b[p]);
p=j;
}
else break;
}
for(int i=1;i<n;i++) cout<<b[i]<<" ";
cout<<b[n]<<endl;
}
return 0;
}
/***************************
The end!
***************************/