暴力
开一个priority_queue push pop ,,,,,,, 太慢了
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
| #include <iostream> #include <queue> #include <vector> using namespace std; const int maxn=10000; vector <int> num; int main() {
int time; scanf("%d",&time); while ( time-- ) { priority_queue<int> que; int n; scanf("%d",&n); for (int i=1;i<=n;i++) { int t; scanf("%d",&t); que.push(t); if( i%2 == 1) { int len=i/2; while ( len-- ) num.push_back(que.top()),que.pop(); printf("%d ",que.top()); while ( !num.empty() ) que.push(num.back()),num.pop_back(); } } printf("\n"); } return 0; }
|
对顶堆
- 分别用一个大根堆和小根堆,如序列
len=7
将[1,4]
放大根堆,其余放入小根堆
len%2 == 1
时肯定 两个堆大小差距为1,且大根堆的数<=
中位数X,小根堆的数>=x
- 每次判断数i与中位数
maxque.top()
的大小,i>x
则加入小堆,同理
- 维护
maxque.size()=minque.size()+1
这一性质,相互移动堆顶的数字
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
| #include <iostream> #include <queue> using namespace std; priority_queue<int> maxque; priority_queue<int> minque; int main() { freopen("a.txt","r",stdin); int t; scanf("%d",&t); while (t--) { int n; scanf("%d",&n); for (int i=1;i<=n;i++) { int x; scanf("%d",&x); if( maxque.empty() ) maxque.push(x); else { if( x>maxque.top() ) minque.push(-x); else maxque.push(x); } while ( maxque.size() < minque.size() ) { int temp=minque.top(); minque.pop(); maxque.push(-temp); } while ( minque.size() < maxque.size()-1 ) { int temp=maxque.top(); maxque.pop(); minque.push(-temp); } if( i%2 == 1) printf("%d ",maxque.top() ); } printf("\n"); while ( !maxque.empty() ) maxque.pop(); while ( !minque.empty() ) minque.pop(); } return 0; }
|
离线做法(链表+map)
- 排序后加入到链表,按输入的逆序删除并且记录中位数,然后逆序输出记录的中位数