洛谷P1168 中位數
阿新 • • 發佈:2021-10-18
【解題報告】洛谷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)間的資料
這裡可以直接使用第二個用法,然後加上一個 upper_bound()
就行了
話說我第一次知道有這種用法
如果資料是單調遞減會不會炸掉啊
#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的更快一些
#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;
}
本博文為wweiyi原創,若想轉載請聯絡作者,qq:2844938982