본문 바로가기
ps

[백준] 3117 - YouTube

by kariskan 2023. 8. 2.

https://www.acmicpc.net/problem/3117

 

3117번: YouTube

첫째 줄에 N, K, M이 주어진다. (1 ≤ N,K ≤ 100,000) (1 ≤  M ≤  1,000,000,000) N은 학생의 수, K는 동영상의 개수, M은 남은 수업 시간이다. 둘째 줄에는 1보다 크거나 같고, K보다 작거나 같은 수가 N개

www.acmicpc.net

 

많이 봐왔던 sparse matrix 문제이다. 희소 배열에 대한 개념이 없다면 여기를 참고해도 좋다.

이 문제의 입력으로 사이클이 생기는 그래프가 주어질 수 있다. 그래서 M의 범위가 10억이어도 상관이 없는 것이고, M의 범위가 10억 인 만큼 sparse matrix를 다음과 같이 정의할 것이다.

p[i][j] = 정점 i의 2^j 번째 부모, j는 최소 31(2^30 = 10억 이상)

 

처음 K개의 입력으로 p[i][0]을 채워 넣을 수 있을 것이다.

memset(p, -1, sizeof(p));
for (int i = 1; i <= k; i++) {
    cin >> p[i][0];
}

 

다음은 p[i][0]의 정보를 바탕으로 p[i][1] ~ p[i][30]의 정보를 채워 넣을 수 있을 것이다.

for (int i = 1; i <= 30; i++) {
    for (int j = 1; j <= k; j++) {
        if (p[p[j][i - 1]][i - 1] != -1) {
            p[j][i] = p[p[j][i - 1]][i - 1];
        }
    }
}

 

다음은 M분에 시청하는 동영상 번호를 출력하면 되는데, 주의해야 할 점은 여기서 1분에 시청하는 동영상은 추천 동영상이 아니라 맨 처음 시청하는 동영상인 것이다.

따라서 우리가 구해야 할 것은 맨 처음 시청하는 동영상의 m - 1번째 부모이다.

#include <iostream>
#include <cstring>
using namespace std;

int n, k, m;
int p[100001][31], inp[100001];

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> k >> m;

    for (int i = 1; i <= n; i++) {
        cin >> inp[i];
    }

    memset(p, -1, sizeof(p));
    for (int i = 1; i <= k; i++) {
        cin >> p[i][0];
    }

    for (int i = 1; i <= 30; i++) {
        for (int j = 1; j <= k; j++) {
            if (p[p[j][i - 1]][i - 1] != -1) {
                p[j][i] = p[p[j][i - 1]][i - 1];
            }
        }
    }

    for (int i = 1; i <= n; i++) {
        int target = m - 1;
        while (target) {
            for (int j = 30; j >= 0; j--) {
                if (target >= (1 << j)) {
                    inp[i] = p[inp[i]][j];
                    target -= (1 << j);
                    break;
                }
            }
        }
        cout << inp[i] << ' ';
    }
}

'ps' 카테고리의 다른 글

[백준] 2917 - 늑대 사냥꾼  (0) 2023.08.08
[백준] 3114 - 사과와 바나나  (0) 2023.08.07
[백준] 21922 - 학부 연구생 민상  (0) 2023.08.02
[백준] 2281 - 데스노트  (0) 2023.08.01
[백준] 17828 - 문자열 화폐  (0) 2023.08.01

댓글