我终于会堆!了!
题目描述
如题,初始小根堆为空,我们需要支持以下3种操作:
操作1: 1 x 表示将x插入到堆中
操作2: 2 输出该小根堆内的最小数
操作3: 3 删除该小根堆内的最小数
输入输出格式
输入格式:
第一行包含一个整数N,表示操作的个数
接下来N行,每行包含1个或2个正整数,表示三种操作,格式如下:
操作1: 1 x
操作2: 2
操作3: 3
输出格式:
包含若干行正整数,每行依次对应一个操作2的结果。
输入输出样例
输入样例#1:
5 1 2 1 5 2 3 2
输出样例#1:
2 5
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=15
对于70%的数据:N<=10000
对于100%的数据:N<=1000000(注意是6个0。。。不过不要害怕,经过编者实测,堆是可以AC的)
样例说明:
故输出为2、5
1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 6 int n,v,len; 7 int x[2222222]; 8 9 void swap(int &a,int &b)//交换左右孩子 10 { 11 int qwq=a;//用qwq交换 12 a=b; 13 b=qwq; 14 } 15 16 void c1(int d)//插入堆中,并排序 17 {//将最小的存在x【1】中 18 int now, next; 19 x[++len] = d; 20 now = len; 21 while(now > 1) 22 { 23 next = now >> 1; 24 if(x[now] >= x[next])break; 25 swap(x[now], x[next]); 26 now = next; 27 } 28 } 29 30 void c2()//输出最小值 31 { 32 printf("%d\n",x[1]); 33 } 34 35 void c3()//进行删除x【1】(即最小值 ) 36 { 37 int now, next, res; 38 res = x[1]; 39 x[1] = x[len--]; 40 now = 1; 41 while(now * 2 <= len) 42 { 43 next = now * 2; 44 if(next < len && x[next + 1] < x[next])next++; 45 if(x[now] <= x[next]) return; 46 swap(x[now], x[next]); 47 now = next; 48 } 49 } 50 51 int main() 52 { 53 int d; 54 scanf("%d",&n); 55 for(int i=1;i<=n;i++) 56 { 57 scanf("%d",&v); 58 switch(v) 59 { 60 case 1: 61 scanf("%d",&d); 62 c1(d); 63 break; 64 case 2: 65 c2(); 66 break; 67 case 3: 68 c3(); 69 break; 70 default: 71 break; 72 } 73 } 74 return 0; 75 }
时间: 2024-10-18 02:37:41