【解题报告】洛谷P1168 中位数
题目链接
https://www.luogu.com.cn/problem/P1168
思路
这道题目是个数据结构
由于数据结构很长时间没有码了,所以就开了一个这个
发现不怎么有思路
本来想开一个数组,然后比较位置,然后加入数组的,发现炸掉
然后主流的思路有以下两种,我也基本搞懂了
STL大法
stl大法好!
用一个vector,然后直接查询就好了
然后vector我似乎不太会用,所以我就查了一下下百度
-
void push_back(const T& x):向量尾部增加一个元素X
-
iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
-
iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
-
iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据
——https://www.cnblogs.com/zsq1993/p/5929806.html
这里可以直接使用第二个用法,然后加上一个 upper_bound() 就行了
话说我第一次知道有这种用法
如果数据是单调递减会不会炸掉啊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> using namespace std; const int maxn=100005; int n; vector <int> a; int main() { cin>>n; for(int i=1;i<=n;i++) { int x; cin>>x; a.insert(upper_bound(a.begin(),a.end(),x),x); if(i&1) cout<<a[(i-1)/2]<<'\n'; } return 0;
|
对顶堆
还是用到了stl
但是思想完全不一样
我们建一个大根堆,建一个小根堆
然后就完了
左边是一个大根堆,堆顶靠近mid,右边是一个小根堆,堆顶靠近mid
每次查询的时候调整堆的大小,是两个堆的大小相差为1,多的那个第一个就是中位数,速度会比用vector的更快一些
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> using namespace std; const int maxn=100005; int n; int a[maxn]; int jdz(int x) { return x>0? x:-x; } priority_queue <int,vector<int>,less<int> > q1; priority_queue <int,vector<int>,greater<int> > q2; int main() { cin>>n; cin>>a[1]; int mid=a[1]; cout<<mid<<'\n'; for(int i=2;i<=n;i++) { cin>>a[i]; if(a[i]>mid) q2.push(a[i]); else q1.push(a[i]); if(i&1) { while(q1.size()!=q2.size()) { if(q1.size()>q2.size()) { q2.push(mid); mid=q1.top(); q1.pop(); } else { q1.push(mid); mid=q2.top(); q2.pop(); } } cout<<mid<<'\n'; } } return 0; }
|