ZJUT1647小X的苹果优先队列

    技术2022-05-13  15

    Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1647

     

    一道优先队列的题目。

     

    之前看了不懂得做,因为没学过。

     

    昨天看了堆排序以及用堆构建优先队列,所以今天试了下。

     

    两次CE(郁闷……),两次WA(一次不行,因为要赶快上课,所以匆匆又改了一下,还是不行……),然后下课回来,检查了一下,修改了一点,然后提交,然后AC。

     

    之前看的时候不知道应该怎样利用优先队列,不过看了一会很快就想出来了。

     

    思路:

     

    把数列分成两个堆。即从排好序的数组从中间分开,左边建成最大堆,右边建成最小堆。那么最大堆的取值和最小堆的取值就是中位数。当个数为奇数时取最大堆,当个数为偶数时同时取两个堆。

     

    还有一点就是插入一个数的时候,要判断此时的个数是偶数还是奇数,应该插在最大堆还是最小堆。

     

    当数大于最大堆时:

    1)如果此时为奇数,则应该插在最小堆。

    2)如果此时为偶数:

        【1】如果这个数小于最小堆,则应该插在最大堆。

        【2】如果这个数不小于最小堆,则应该把最小堆的最小值插入到最大堆,同时把这个数插入到最小堆。

    当数小于最大堆时:

    1)如果此时为奇数,则应该把最大堆的最大值插入到最小堆,同时把这个数插入到最大堆。

    2)如果此时为偶数,则直接把这个数插入到最大堆。

     

    以下贴代码:

     

    #include <iostream> #include <cstring> using namespace std; int maxheap[100005],minheap[100005],lenmax,lenmin; void exchange(int &a, int &b) { int t=a; a = b; b = t; } void max_heap_insert(int v)//最大堆的插入 { lenmax++; maxheap[lenmax] = v; int i=lenmax; while(i>1 && maxheap[i/2]<maxheap[i]) { exchange(maxheap[i/2], maxheap[i]); i /= 2; } } void min_heap_insert(int v)//最小堆的插入 { lenmin++; minheap[lenmin] = v; int i=lenmin; while(i>1 && minheap[i/2]>minheap[i]) { exchange(minheap[i/2], minheap[i]); i /= 2; } } void max_heapify(int i)//最大堆的维护 { int l = 2*i, r = 2*i+1, largest; if (l<=lenmax && maxheap[l]>maxheap[i]) { largest = l; } else { largest = i; } if (r<=lenmax && maxheap[r]>maxheap[largest]) { largest = r; } if (largest!=i) { exchange(maxheap[i],maxheap[largest]); max_heapify(largest); } } void min_heapify(int i)//最小堆的维护 { int l = 2*i, r = 2*i+1, smallest; if (l<=lenmin && minheap[l]<minheap[i]) { smallest = l; } else { smallest = i; } if (r<=lenmin && minheap[r]<minheap[smallest]) { smallest = r; } if (smallest!=i) { exchange(minheap[i],minheap[smallest]); min_heapify(smallest); } } void build_max_heap()//建立最大堆 { int i; for (i=lenmax; i>0; i--) { max_heapify(i); } } void build_min_heap()//建立最小堆 { int i; for (i=lenmin; i>0; i--) { min_heapify(i); } } int main() { int n,m,i,mid,x; bool single; char ch[10],drop[]="drop",query[]="query"; scanf("%d", &n); while(scanf("%d", &n)!=EOF) { if (n%2==0) { mid = n/2; single = false; } else { mid = n/2+1; single =true; } lenmax = mid; lenmin = n - mid; for (i=mid; i>0; i--) scanf("%d", &maxheap[i]); for (i=1; i<=n-mid; i++) scanf("%d", &minheap[i]); // build_max_heap();//这道题中这两步可以省略 // build_min_heap();//因为按上面的方式读入已经是建立好了堆 scanf("%d", &m); for (i=0; i<m; i++) { scanf("%s", ch); if (strcmp(drop, ch)==0) { scanf("%d", &x); if (x>=maxheap[1]) { if (single) { min_heap_insert(x); } else { if (x>minheap[1]) { max_heap_insert(minheap[1]); minheap[1] = x; min_heapify(1); } else { max_heap_insert(x); } } } else { if (single) { min_heap_insert(maxheap[1]); maxheap[1] = x; max_heapify(1); } else { max_heap_insert(x); } } if (single) single = false; else single = true; } else { if (single) { printf("%d/n", maxheap[1]); } else { printf("%d %d/n", maxheap[1], minheap[1]); } } } } return 0; }


    最新回复(0)