목표 : 카카오 코드 페스티벌 2018 예선 E, F번 풀기
https://www.acmicpc.net/problem/15957
15957번: 음악 추천
입력의 첫째 줄에는 세 정수로, 곡의 수 N(2 ≤ N ≤ 100,000), 추천 알고리즘의 결과 데이터의 수 K(1 ≤ K ≤ 100,000), 목표 점수 J(10 ≤ J ≤ 108)가 주어진다. 각각의 곡은 1번부터 N번까지 번호가 붙어 있다. 다음 줄에 N-1개의 곡 번호가 주어지는데, 이는 2번 곡부터 해당 곡의 부모 노드가 되는 곡의 번호이다. 1번 곡은 부모 노드가 없다. 다음 줄에 N개의 수가 주어지는데, 이는 1번 곡부터 해당 곡을 부른 가
www.acmicpc.net
해결 방법
> 입력을 받아 트리를 그린다.
> 각 노드의 서브트리의 노드 개수를 구한다.(가중치를 나누기 위함)
> dfs를 돌면서 가중치를 적용시킨다.
> 트리를 순회하면서 가중치가 목표 점수에 도달하면 걸린시간을 체크한다.
결과
> 시간 초과
> 내가 생각한 이유 : 노드의 개수가 10만개인데 내가 짠 코드는 dfs를 10만번 돌고 또 돌아야 하기 떄문에 시간초과가 난 것 같다.
코드
import sys
from collections import defaultdict
sys.setrecursionlimit(10 ** 6)
def DFS_visit(adj, u, visited):
if num_subnode[u] != None:
return
visited.append(u)
for v in adj[u]:
if v not in visited:
DFS_visit(adj, v, visited)
def DFS(adj, s):
visited =[]
DFS_visit(adj, s, visited)
num_subnode[s] = len(visited)
def DFS_visit_cal(adj, u, visited, time, w):
visited.append(u)
index = result[u - 1][2] - 1
if not check[index]:
result[u - 1][1] += w
if (result[u - 1][1] // singer_count[result[u - 1][2]]) >= target_score:
check[index] = True
output[result[u - 1][2]] = time
for v in adj[u]:
if v not in visited:
DFS_visit_cal(adj, v, visited, time, w)
def DFS_cal(adj, s, time, w):
visited =[]
DFS_visit_cal(adj, s, visited, time, w)
musictree = defaultdict(set)
num_music, num_data, target_score = map(int, input().split())
parent_node = list(map(int, input().split()))
parent_node.insert(0,0)
#가수 처리
singer = list(map(int, input().split()))
singer_count = defaultdict(int)
for i in singer:
singer_count[i] += 1
for i in range(1, num_music + 1):
for j in range(num_music):
if parent_node[j] == i:
musictree[i].add(j + 1)
num_subnode = list(None for i in range(num_music + 1)) #서브트리의 노드 개수
for i in range(1, num_music + 1):
DFS(musictree,i)
result = list()
for i in range(num_music):
result.append([0,0,singer[i]]) #시간, 가중치, 가수
check = [False for i in range(num_music)]
output = defaultdict(lambda: -1)
for i in range(num_music):
time, subtree, weight = map(int, input().split())
DFS_cal(musictree, subtree, time, weight//num_subnode[subtree])
for i in singer:
print(output[i])
https://www.acmicpc.net/problem/15958
15958번: 프로도의 100일 준비
입력의 첫째 줄에는 직각다각형의 꼭짓점의 개수 N(4 ≤ N ≤ 500,000)이 주어진다. 이어지는 N줄 각각엔 직각다각형 꼭짓점의 좌표를 나타내는 정수 (x, y) (0 ≤ x, y ≤ 109)가 공백을 사이에 두고 주어진다. 입력 다각형의 시작점은 원점 (0,0)이고, 꼭짓점이 시계방향 순서로 주어진다. 즉, 연속하는 두 개의 꼭짓점은 직각다각형의 한 선분을 이루며, x좌표는 단조증가한다. 참고로, 시작점과 끝점만 y좌표가 0이다. 연속하는 세 점이
www.acmicpc.net
해결 방법
> 히스토그램을 y축의 변화를 기준으로 직사각형으로 나눈다.
> x변의 최대값과 y변의 최솟값을 구한다.
> 조건을 달아 연산하면 될 것 같다.
음악추천에 시간을 너무 많이 써서 위의 단계에서 끝났다.
'CNU 학습 동아리 > 2020 동계 학습 동아리' 카테고리의 다른 글
2020 동계 학습 동아리_7회차_2020-02-17(월) (0) | 2020.02.18 |
---|---|
2020 동계 학습 동아리_5회차_2020-02-11(화) (0) | 2020.02.12 |
2020 동계 학습 동아리_4회차_2020-02-10(월) (0) | 2020.02.10 |
2020 동계 학습 동아리_3회차_2020-02-07(금) (0) | 2020.02.07 |
2020 동계 학습 동아리_2회차_2020-02-04(화) (0) | 2020.02.04 |
댓글