PAT_A1098
PAT甲级1098.
目录
A1098
题目
样例
样例1
输入:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
输出:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
样例2
输入:
10
3 1 2 8 7 5 9 4 6 0
6 4 5 1 0 3 2 7 8 9
输出:
Heap Sort
5 4 3 1 0 2 6 7 8 9
思路和坑点
利用插入排序的特征,前半部分有序,后半部分和原序列相同的特性。辨别是不是插入排序,如果是则在插入一个元素,否则是堆排序,可以直接利用c++11标准中的heap的相关操作,找到不满足堆的位置,然后将前边满足堆的部分弹出堆顶元素到尾巴上。heap的操作可以参考PAT总结那篇博客中的总结,也可以手动写函数实现。
AC代码
#include<bits/stdc++.h>
using namespace std;
int main(void){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt","r",stdin);
#endif
int n,i=0,j;
cin>>n;
vector<int> v(n),mid(n); //存放原始序列和中间序列
for(i=0;i<n;i++) //读入数据
scanf("%d",&v[i]);
for(i=0;i<n;i++)
scanf("%d",&mid[i]);
for(i=0;i<n-1;i++){ //从中间序列开始,找到第一个不符合递增序列的下标j
if(mid[i]>mid[i+1]){
j=i+1;
i++;break;
}
}
for(j;j<n;j++) //从j开始,往后比较原始序列和中间序列
if(v[j]!=mid[j]) break;
if(j==n){ //如果后半部分和原始序列相同,则为插入排序
puts("Insertion Sort");
sort(mid.begin(),mid.begin()+i+1);
}
else{
puts("Heap Sort"); //否则为堆排序
auto pos=is_heap_until(mid.begin(),mid.end(),less<int>());
pop_heap(mid.begin(),pos); //查找第一个不满足堆的位置(大根堆),然后将前半部分的堆pop操作
}
for(int i=0;i<n;i++){ //输出结果
if(i) putchar(' ');
printf("%d",mid[i]);
}
return 0;
}