문제: icpc.me/14434
놀이기구를 타는 키 제한이 존재하고 각 날마다 키가 자라는 아이와 어떤 놀이기구를 타는지 물어보는 질의들이 주어질 때 각 날마다 아이들이 타는 놀이기구의 수를 출력하는 문제이다.
이 문제는 각 질의에 대하여 해당 놀이기구를 탈 수 있는 첫번 째 날을 구해주면 그 날 이후는 해당 놀이기구를 항상 탈 수 있으니 psum으로 해결 가능하다.
문제는 질의마다 첫번 째 놀이기구의 탑승 가능일을 구해주는 일이다.
우선 질의에 대해 첫번 째 놀이기구의 탑승 가능일을 탐색해야하므로 mid값을 날짜로 생각을 하자.
그럼 mid일에 놀이기구를 타야하는 두 아이의 키를 가져와야 하는데 이는 2차원 벡터로 각 아이에 대해 키가 크는 날짜를 벡터에 삽입해준다면 upper_bound로 계산해줄 수 있다.
따라서 모든 질의에 대해서 답이 되는 구간을 정해준 뒤 답을 출력해주면 된다.
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 | #include <cstdio> #include <algorithm> #include <vector> using namespace std; int n, m, k, q, a[200020], x, y, z, r[200020]; vector<vector<int>> vt; int main() { scanf("%d%d%d%d", &n, &m, &k, &q); vt.resize(n + 1); for (int i = 1; i <= m; i++) scanf("%d", &a[i]); for (int i = 1; i <= k; i++) { scanf("%d", &x); vt[x].push_back(i); } for (int i = 0; i < q; i++) { scanf("%d%d%d", &x, &y, &z); int lo = 0, hi = 200020; while (lo < hi) { int mid = (lo + hi) >> 1; int xx = upper_bound(vt[x].begin(), vt[x].end(), mid) - vt[x].begin(); int yy = upper_bound(vt[y].begin(), vt[y].end(), mid) - vt[y].begin(); if (xx + yy >= a[z]) hi = mid; else lo = mid + 1; } r[lo]++; } for (int i = 1; i <= k; i++) { printf("%d\n", r[i]); r[i + 1] += r[i]; } return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)12963 달리기 (0) | 2017.06.15 |
---|---|
BOJ)8217 유성 (1) | 2017.06.14 |
BOJ)1396 크루스칼의 공 (3) | 2017.06.13 |
BOJ)10319 좀비 아포칼립스 (0) | 2017.06.12 |
BOJ)5651 완전 중요한 간선 (0) | 2017.06.12 |