본문 바로가기

알고리즘 관련/BOJ

BOJ)14434 놀이기구1

문제: 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