偷懒的桐桐
时间限制: 1 Sec 内存限制: 64 MB
提交: 26 解决: 9
[提交][状态][讨论版]
题目描述
桐桐的老师布置桐桐写一个小根堆,但是桐桐不会堆的操作,所以想了一个偷懒的办法:
堆
是一棵完全二叉树,每个结点有一个权。小根堆的根的权最小,且根的两个子树也是一个堆。可以用一个数组a来记录一棵完全二叉树,a[1]为根结点,若结点
a[j]不是根结点,那么它的父亲为a[j div 2];若结点a[k]不是叶子结点,那么它的左儿子为a[2k],它的右儿子为a[2k+1]。
桐桐希望一组数据按一定顺序依次插入数组中(即第i个数为a[i]),最后得出来就已经是一个堆,即不需要任何交换操作,若有多种方法,输出字典序最大的一组,使得这个数据更乱。
输入
输入的第1行为一个正整数n,为插入的数字的个数;
第2行包含n个正整数,为所有需要插入的数字,数字之间用空格隔开。
为了简化题目,数据保证n=2k-1,即保证最后的堆是一棵满二叉树。
输出
输出包括1行,为插入的序列,数字之间用空格隔开,行末换行并没有空格。
样例输入
3 10 2 1
样例输出
1 10 2
提示
样例说明 1 2 10 与1 10 2都是满足要求的插入序列,但是1 10 2的字典序更大。
20%的数据:n≤7;
30%的数据:n≤15;
50%的数据:n≤1023;
100%的数:n≤65535,所有数字不超过108,且各不相同。
#include <iostream> #include <cstring> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <time.h> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define inf 0x3f3f3f3f #define mod 1000000007 typedef long long ll; using namespace std; const int N = 100000; const int MAX = 2000; int n,m,maxn=-1,cnt=0; int a[N],s[N]; void dfs(int l,int r,int num) { int mid=(l+r)/2+1; s[num*2]=a[mid]; s[num*2+1]=a[l+1]; cnt+=2; if(mid<r) { dfs(mid,r,num*2); dfs(l+1,mid-1,num*2+1); } if(cnt>=n) { printf("%d",s[1]); for(int i=2; i<=cnt; i++) { printf(" %d",s[i]); } printf("\n"); exit(0); } } int main() { cin>>n; for(int i=0; i<n; i++) { cin>>a[i]; } if(n==1){ cout<<a[0]<<endl; exit(0); } sort(a,a+n); s[1]=a[0];cnt++; dfs(0,n-1,1); return 0; }
时间: 2024-10-12 02:40:57