#include<cstdio> #include<queue> using namespace std; int main() { int n, a, k; char op[5]; while(~scanf("%d%d", &n, &k)) { priority_queue<int,vector<int>,greater<int> > pq; while(n--) { scanf("%s", op); if(op[0] == 'I') { scanf("%d",&a); if(pq.size()<k) pq.push(a); elseif(a > pq.top()) pq.push(a),pq.pop(); } elseprintf("%d\n", pq.top()); } } return0; }
The kth great number
Problem Description
Xiao Ming and Xiao Bao are playing a simple Numbers game. In a round Xiao Ming can choose to write down a number, or ask Xiao Bao what the kth great number is. Because the number written by Xiao Ming is too much, Xiao Bao is feeling giddy. Now, try to help Xiao Bao. Input
There are several test cases. For each test case, the first line of input contains two positive integer n, k. Then n lines follow. If Xiao Ming choose to write down a number, there will be an “ I” followed by a number that Xiao Ming will write down. If Xiao Ming choose to ask Xiao Bao, there will be a “Q”, then you need to output the kth great number. Output
The output consists of one integer representing the largest number of islands that all lie on one line. Sample Input
8 3 I 1 I 2 I 3 Q I 5 Q I 4 Q Sample Output
1 2 3
HintXiao Ming won’t ask Xiao Bao the kth great number when the number of the written number is smaller than k. (1=<k<=n<=1000000).
voidbuild(int p, int s, int e) { if(s == e) { scanf("%d", &sum[p]); return; } build(lc), build(rc); pushup(p); }
voidupdate(int p, int s, int e, int a, int b) { if(s == e && e == a) { sum[p] += b; return; } if( a <= mid) update(lc, a, b); elseupdate(rc, a, b); pushup(p); }
int query(int p, int s, int e, int l, int r) { if(s >= l && e <= r) return sum[p]; if(r <= mid) returnquery(lc, l, r); if(l > mid) returnquery(rc, l, r); returnquery(lc, l, mid) + query(rc, mid + 1, r); }
int main() { int cas, n, a, b; char c[20]; scanf("%d", &cas); for(int k = 1; k <= cas; ++k) { printf("Case %d:\n", k); scanf("%d", &n); build(1, 1, n); while(scanf("%s", c), c[0] != 'E') { scanf("%d%d", &a, &b); if(c[0] == 'Q') printf("%d\n", query(1, 1, n, a, b)); elseif(c[0] == 'A') update(1, 1, n, a, b); elseupdate(1, 1, n, a, -b); } } return0; }
D. Handshakes On February, 30th n students came in the Center for Training Olympiad Programmers (CTOP) of the Berland State University. They came one by one, one after another. Each of them went in, and before sitting down at his desk, greeted with those who were present in the room by shaking hands. Each of the students who came in stayed in CTOP until the end of the day and never left.
At any time any three students could join together and start participating in a team contest, which lasted until the end of the day. The team did not distract from the contest for a minute, so when another student came in and greeted those who were present, he did not shake hands with the members of the contest writing team. Each team consisted of exactly three students, and each student could not become a member of more than one team. Different teams could start writing contest at different times.
Given how many present people shook the hands of each student, get a possible order in which the students could have come to CTOP. If such an order does not exist, then print that this is impossible.
Please note that some students could work independently until the end of the day, without participating in a team contest.
Input
The first line contains integer n (1 ≤ n ≤ 2·105) — the number of students who came to CTOP. The next line contains n integersa1, a2, …, a**n (0 ≤ a**i < n), where a**i is the number of students with who the i-th student shook hands. Output
If the sought order of students exists, print in the first line “Possible” and in the second line print the permutation of the students’ numbers defining the order in which the students entered the center. Number i that stands to the left of number j in this permutation means that the i-th student came earlier than the j-th student. If there are multiple answers, print any of them.
If the sought order of students doesn’t exist, in a single line print “Impossible”.
#include <bits/stdc++.h> using namespace std; const int N = 105; int v[N]; int main() { int v1, v2, t, d, k; while(~scanf("%d%d%d%d", &v1, &v2, &t, &d)) { v[0] = v1, v[t - 1] = v2; int le = 0, ri = t - 1, ans = 0; while(le < ri - 1) { if(v[le] < v[ri]) v[le + 1] = v[le++] + d; else v[ri - 1] = v[ri--] + d; } for(int i = 0; i < t; ++i) ans += v[i]; printf("%d\n", ans); } return0; } //Last modified : 2015-04-13 00:27
B. Covered Path
The on-board computer on Polycarp’s car measured that the car speed at the beginning of some section of the path equals v1 meters per second, and in the end it is v2 meters per second. We know that this section of the route took exactly t seconds to pass.
Assuming that at each of the seconds the speed is constant, and between seconds the speed can change at most by d meters per second in absolute value (i.e., the difference in the speed of any two adjacent seconds does not exceed d in absolute value), find the maximum possible length of the path section in meters. Input
The first line contains two integers v1 and v2 (1 ≤ v1, v2 ≤ 100) — the speeds in meters per second at the beginning of the segment and at the end of the segment, respectively.
The second line contains two integers t (2 ≤ t ≤ 100) — the time when the car moves along the segment in seconds, d (0 ≤ d ≤ 10) — the maximum value of the speed change between adjacent seconds.
It is guaranteed that there is a way to complete the segment so that:
Output
Print the maximum possible length of the path segment in meters. Sample test(s)
input 5 6 4 2
output 26 input 10 10 10 0
output 100
Note
In the first sample the sequence of speeds of Polycarpus’ car can look as follows: 5, 7, 8, 6. Thus, the total path is 5 + 7 + 8 + 6 = 26meters.
In the second sample, as d = 0, the car covers the whole segment at constant speed v = 10. In t = 10 seconds it covers the distance of 100 meters.
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 500005; int a[N], r[N], n;
bool cmp(int i, int j) //离散化排序用的比较函数 { return a[i] < a[j]; }
voidadd(int x, int v) { while(x <= n) { a[x] += v; x += x & -x; } }
int sum(int x) { int ret = 0; while(x) { ret += a[x]; x -= x & -x; } return ret; }
int main() { while(scanf("%d", &n), n) { for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), r[i] = i; sort(r + 1, r + n + 1, cmp); //离散化 用数排序后的下标代替数
long long ans = 0; memset(a, 0, sizeof(a)); for(int i = 1; i <= n; ++i) { ans += sum(n) - sum(r[i]); add(r[i], 1); } printf("%lld\n", ans); }
return0; }
Ultra-QuickSort
Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 9 1 0 5 4 , Ultra-QuickSort produces the output 0 1 4 5 9 . Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 – the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
#include <bits/stdc++.h> using namespace std; const int N = 105, M = 10005; int d[M], t[M], n, m; char g[N][M];
voidgett(int r, int c) { int p = (c + 1) % m, cnt = t[c] = 0; while(p != c) //顺时针转一圈 { if(g[r][p] == '1') cnt = -1; t[p] = ++cnt; p = (p + 1) % m; }
p = (p + m - 1) % m, cnt = 0; while(p != c) //逆时针转一圈 { if(g[r][p] == '1') cnt = -1; if(t[p] > cnt + 1) t[p] = cnt + 1; d[p] += t[p], ++cnt; p = (p + m - 1) % m; } }
int main() { int i, j; while(~scanf("%d%d", &n, &m)) { memset(d, 0, sizeof(d)); for(i = 0; i < n; ++i) scanf("%s", g[i]);
for(i = 0; i < n; ++i) { for(j = 0; j < m; ++j) if(g[i][j] == '1') gett(i, j), j = m; if(j == m) break; } sort(d, d + m); printf("%d\n", i < n ? -1 : d[0]); } return0; }
C. Shifts You are given a table consisting of n rows and m columns. Each cell of the table contains a number, 0 or 1. In one move we can choose some row of the table and cyclically shift its values either one cell to the left, or one cell to the right.
To cyclically shift a table row one cell to the right means to move the value of each cell, except for the last one, to the right neighboring cell, and to move the value of the last cell to the first cell. A cyclical shift of a row to the left is performed similarly, but in the other direction. For example, if we cyclically shift a row “00110” one cell to the right, we get a row “00011”, but if we shift a row “00110” one cell to the left, we get a row “01100”.
Determine the minimum number of moves needed to make some table column consist only of numbers 1.
Input
The first line contains two space-separated integers: n (1 ≤ n ≤ 100) — the number of rows in the table and m (1 ≤ m ≤ 104) — the number of columns in the table. Then n lines follow, each of them contains m characters “0” or “1”: the j-th character of the i-th line describes the contents of the cell in the i-th row and in the j-th column of the table.
It is guaranteed that the description of the table contains no other characters besides “0” and “1”. Output
Print a single number: the minimum number of moves needed to get only numbers 1 in some column of the table. If this is impossible, print -1.
#include <bits/stdc++.h> using namespace std; const int N = 10005; const double eps = 1e-9; int a[N], b[N], c[N], n;
double getr(double x) { double r = a[0] * x * x + b[0] * x + c[0], t; for(int i = 1; i < n; ++i) { t = a[i] * x * x + b[i] * x + c[i]; if(t > r) r = t; } return r; }
int main() { int cas; scanf("%d", &cas); while(cas--) { scanf("%d", &n); for(int i = 0; i < n; ++i) scanf("%d%d%d", &a[i], &b[i], &c[i]);
double l = 0, r = 1000, m, mm; while(l + eps < r) { m = (l + r) / 2; mm = (m + r) / 2; if(getr(m) < getr(mm)) r = mm; else l = m; } printf("%.4f\n", getr(l)); } return0; }
Error Curves
Problem Description
Josephina is a clever girl and addicted to Machine Learning recently. She pays much attention to a method called Linear Discriminant Analysis, which has many interesting properties. In order to test the algorithm’s efficiency, she collects many datasets. What’s more, each data is divided into two parts: training data and test data. She gets the parameters of the model on training data and test the model on test data. To her surprise, she finds each dataset’s test error curve is just a parabolic curve. A parabolic curve corresponds to a quadratic function. In mathematics, a quadratic function is a polynomial function of the form f(x) = ax2 + bx + c. The quadratic will degrade to linear function if a = 0. It’s very easy to calculate the minimal error if there is only one test error curve. However, there are several datasets, which means Josephina will obtain many parabolic curves. Josephina wants to get the tuned parameters that make the best performance on all datasets. So she should take all error curves into account, i.e., she has to deal with many quadric functions and make a new error definition to represent the total error. Now, she focuses on the following new function’s minimum which related to multiple quadric functions. The new function F(x) is defined as follows: F(x) = max(Si(x)), i = 1…n. The domain of x is [0, 1000]. Si(x) is a quadric function. Josephina wonders the minimum of F(x). Unfortunately, it’s too hard for her to solve this problem. As a super programmer, can you help her? Input
The input contains multiple test cases. The first line is the number of cases T (T < 100). Each case begins with a number n (n ≤ 10000). Following n lines, each line contains three integers a (0 ≤ a ≤ 100), b (|b| ≤ 5000), c (|c| ≤ 5000), which mean the corresponding coefficients of a quadratic function. Output
For each test case, output the answer in a line. Round to 4 digits after the decimal point. Sample Input
#include <map> #include <cstdio> #include <cstring> using namespace std; const int N = 12; int x[] = {0, 0, -1, 1}; int y[] = { -1, 1, 0, 0}; char g[N][N] , v[N][N]; int n, m, nu, cnt, ret; pair<int, int> q[N * N], p[N * N];
voiddfs(int r, int c) { if(g[r][c] != '#') return; p[nu++] = make_pair(r, c), g[r][c] = cnt; for(int i = 0; i < 4; ++i) if(r + x[i] >= 0 && c + y[i] >= 0) dfs(r + x[i], c + y[i]); }
voidbfs(int r, int c, int cr, int cc) { int le = 0, ri = 0; q[ri++] = make_pair(r, c); q[ri++] = make_pair(cr, cc); memset(v, 0, sizeof(v)), v[r][c] = v[cr][cc] = 1; while(le < ri) { cr = q[le].first, cc = q[le++].second, ret = v[cr][cc]; for(int i = 0; i < 4; ++i) { r = cr + x[i], c = cc + y[i]; if (r >= 0 && r < n && c >= 0 && c < m && g[r][c] != '.' && !v[r][c]) q[ri++] = make_pair(r, c), v[r][c] = v[cr][cc] + 1; } } }
int main() { int cas, ans, r1, c1, r2, c2; scanf("%d", &cas); for(int k = 1; k <= cas; ++k) { scanf("%d%d", &n, &m); for(int i = 0; i < n; ++i) scanf("%s", g[i]); printf("Case %d: ", k);
nu = cnt = ans = 0; for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) if(g[i][j] == '#') ++cnt, dfs(i, j);
if(cnt < 3) { ans = n * m; for(int i = 0; i < nu; ++i) for(int j = 0; j < nu; ++j) { r1 = p[i].first, c1 = p[i].second; r2 = p[j].first, c2 = p[j].second; if(cnt == 2 && g[r1][c1] == g[r2][c2]) continue; bfs(r1, c1, r2, c2); if(ret < ans) ans = ret; } } printf("%d\n", ans - 1); } return0; }
Problem 2150 Fire Game
Problem Description
Fat brother and Maze are playing a kind of special (hentai) game on an N/*M board (N rows, M columns). At the beginning, each grid of this board is consisting of grass or just empty and then they start to fire all the grass. Firstly they choose two grids which are consisting of grass and set fire. As we all know, the fire can spread among the grass. If the grid (x, y) is firing at time t, the grid which is adjacent to this grid will fire at time t+1 which refers to the grid (x+1, y), (x-1, y), (x, y+1), (x, y-1). This process ends when no new grid get fire. If then all the grid which are consisting of grass is get fired, Fat brother and Maze will stand in the middle of the grid and playing a MORE special (hentai) game. (Maybe it’s the OOXX game which decrypted in the last problem, who knows.)
You can assume that the grass in the board would never burn out and the empty grid would never get fire.
Note that the two grids they choose can be the same.
Input
The first line of the date is an integer T, which is the number of the text cases.
Then T cases follow, each case contains two integers N and M indicate the size of the board. Then goes N line, each line with M character shows the board. “/#” Indicates the grass. You can assume that there is at least one grid which is consisting of grass in the board.
1 <= T <=100, 1 <= n <=10, 1 <= m <=10
Output
For each case, output the case number first, if they can play the MORE special (hentai) game (fire all the grass), output the minimal time they need to wait after they set fire, otherwise just output -1. See the sample input and output for more details.
#include <bits/stdc++.h> using namespace std; const int N = 1005; int x[] = {0, 0, -1, 1}; int y[] = { -1, 1, 0, 0}; int v[N][N], n, m, ans, le, ri; pair<int, int> q[N * N]; char g[N][N];
voidbfs() { int cr, cc, r, c; while(le < ri) { cr = q[le].first, cc = q[le++].second; for(int i = 0; i < 4; ++i) { r = cr + x[i], c = cc + y[i]; if(r < 0 || r >= n || c < 0 || c >= m) ans = ans ? ans : v[cr][cc]; elseif(g[r][c] == '.' && (!v[r][c] || v[cr][cc] + 1 < v[r][c])) v[r][c] = v[cr][cc] + 1, q[ri++] = make_pair(r, c); } } }
int main() { int cas, jr, jc; scanf("%d", &cas); while(cas--) { scanf("%d%d", &n, &m); for(int i = 0; i < n; ++i) scanf("%s", g[i]);
memset(v, 0, sizeof(v)); le = ri = 0; for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) if(g[i][j] == 'F') q[ri++] = make_pair(i, j), v[i][j] = 1; elseif(g[i][j] == 'J') jr = i, jc = j; bfs(); le = ri = ans = 0, v[jr][jc] = 1; q[ri++] = make_pair(jr, jc); bfs(); if(ans) printf("%d\n", ans); elseputs("IMPOSSIBLE"); } return0; }