首页 > 代码库 > UVA - 501 Black Box (优先队列或vector)
UVA - 501 Black Box (优先队列或vector)
Description
Black Box
Black Box |
Our Black Box represents a primitive database. It can save an integer array and has a speciali variable. At the initial moment Black Box is empty and i equals 0. This Black Box processes a sequence of commands (transactions). There are two types of transactions:
- ADD(x): put element x into Black Box;
- GET: increase i by 1 and give an i-minimum out of all integers containing in the Black Box.
Keep in mind that i-minimum is a number located at i-th place after Black Box elements sorting by non-descending.
Example
Let us examine a possible sequence of 11 transactions:N | Transaction | i | Black Box contents after transaction | Answer |
(elements are arranged by non-descending) | ||||
1 | ADD(3) | 0 | 3 | |
2 | GET | 1 | 3 | 3 |
3 | ADD(1) | 1 | 1, 3 | |
4 | GET | 2 | 1, 3 | 3 |
5 | ADD(-4) | 2 | -4, 1, 3 | |
6 | ADD(2) | 2 | -4, 1, 2, 3 | |
7 | ADD(8) | 2 | -4, 1, 2, 3, 8 | |
8 | ADD(-1000) | 2 | -1000, -4, 1, 2, 3, 8 | |
9 | GET | 3 | -1000, -4, 1, 2, 3, 8 | 1 |
10 | GET | 4 | -1000, -4, 1, 2, 3, 8 | 2 |
11 | ADD(2) | 4 | -1000, -4, 1, 2, 2, 3, 8 |
It is required to work out an efficient algorithm which treats a given sequence of transactions. The maximum number of ADD and GET transactions: 30000 of each type.
Let us describe the sequence of transactions by two integer arrays:
- 1.
- : a sequence of elements which are being included into Black Box. A values are integers not exceeding 2 000 000 000 by their absolute value, . For the Example we haveA=(3, 1, -4, 2, 8, -1000, 2).
- 2.
- : a sequence setting a number of elements which are being included into Black Box at the moment of first, second, ... and N-transaction GET. For the Example we have u=(1, 2, 6, 6).
The Black Box algorithm supposes that natural number sequence is sorted in non-descending order, and for eachp ( ) an inequality is valid. It follows from the fact that for thep-element of our u sequence we perform a GET transaction givingp-minimum number from our sequence.
Input
The first line of the input is an integer K, then a blank line followed by K datasets. There is a blank line between datasets.Input for each dataset contains (in given order): . All numbers are divided by spaces and (or) carriage return characters.
Output
For each dataset, write to the output Black Box answers sequence for a given sequence of transactions. The numbers can be separated with spaces and end-of-line characters. Print a blank line between datasets.Sample Input
1 7 4 3 1 -4 2 8 -1000 2 1 2 6 6
Sample Output
3 3 1 2
题意:有n个数,m次询问,对于第i次询问是:在前tmp个中找第i大的数
方法一:优先队列,两个队列,一个从小到大q1,一个从大到小的q2,要求第i大的,其实就是相当于排序后截掉第i个数之后的,那么将这个截掉后的队列倒置就是个最大堆的队列,然后每次调整这个最大堆就行了,保证队首是第i大就是了,这个每次都加进去一个就可以保证是第i大的了
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <queue> using namespace std; const int MAXN = 30010; priority_queue<int, vector<int>, greater<int> > tmp; priority_queue<int, vector<int>, less<int> > ans; int n, m; int num[MAXN]; int main() { int t; scanf("%d", &t); while (t--) { while (!tmp.empty()) tmp.pop(); while (!ans.empty()) ans.pop(); scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &num[i]); int cur = 0; for (int i = 0; i < m; i++) { int cnt; scanf("%d", &cnt); for (; cur < cnt; cur++) tmp.push(num[cur]); ans.push(tmp.top()); tmp.pop(); while (!tmp.empty() && tmp.top() < ans.top()) { cnt = tmp.top(); tmp.pop(); tmp.push(ans.top()); ans.pop(); ans.push(cnt); } printf("%d\n", ans.top()); } if (t) printf("\n"); } return 0; }
方法二:vector的二分,每读一个就插入一个
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <queue> #include <vector> using namespace std; const int MAXN = 30010; int n, m; int num[MAXN]; int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &num[i]); vector<int> v; vector<int>::iterator it; v.clear(); int tmp, cur = 0; int index = 0; for (int i = 0; i < m; i++) { scanf("%d", &tmp); while (v.size() != tmp) { it = lower_bound(v.begin(), v.end(), num[cur]); v.insert(it, num[cur++]); } printf("%d\n", v[index++]); } if (t) printf("\n"); } return 0; }