
이 문제는 설명자체는 간단한데, 트리가 주어지고 1번 쿼리는 트리의 노드를 바꾸는 거고, 2번 쿼리는 현재 만들어진 트리에서 1번 노드에서 v 노드로 가는 길에 1번 노드와 가장 가까운 검정 노드의 번호를 출력하는 문제이다. 이 문제도 여러 가지 풀이 방법이 있는 걸로 알고 있고 가장 대표적인 풀이가 HLD(Heavy heavy Light Decomposition)으로 알고 있는데, 그 풀이가 아닌 ETT(오일러 투어 테크닉) 와 lazy 세그 (느리게 갱신되는 세그먼트 트리), sparse table(희소 배열)을 이용한 풀이를 작성하겠다. 이 문제의 핵심은 2번 쿼리니 1번 쿼리는 2번쿼리의 구조 내에서 구현해 줘야 된다. 그러므로 2번 쿼리부터 설명하겠다. 1부터 v 로 가는 길에서 1에 가장 가까..

이 문제는 초기 문자열과 만들어야하는 문자열이 주어질 때, 각 위치의 스티커를 떼고 붙이고, 구매 등의 방법을 사용해 만들어야하는 문자열이 초기 문자열의 부분 문자열이 되도록 하는 최소값을 구하는 문제이다. 문제 설명만 봤을 때는 어려워 보일 수도 있지만 문자열의 길이가 500이 안되기 때문에 모든 경우를 탐색하면서 최소값을 계산해주면 된다. 부분 문자열을 만들 수 없는 경우 -1을 출력하라고 되어있는데, 이는 구매할 수 있는 스티커 중에 부분 문자열에 필요한 스티커가 없을 때 -1을 출력해주면 된다. 부분 문자열을 만들기 위해서 부분 문자열에 해당될 부분 중, 바꿔야 될 부분의 스티커를 모두 떼준다. 그후 뗀 스티커와 다른 범위에 있는 스티커까지 고려해서 어느걸 고르는 것이 최소값이 되는지 판단해주면 ..

이 문제는 입력된 9개의 숫자 중 합이 100이 되는 7개의 숫자를 고르면 되는 문제인데, 이를 다시 생각해보면 나머지 두명의 값을 제외했을 때 100이 되는 경우를 고르는 문제로 바꿀 수 있다. 이 경우 2중 반복문을 통해 두 수의 합을 전체 합에서 뺀 값이 100이 된다면 해당 두값을 제외한 나머지 값들을 출력해주면 된다. 문제가 스페셜 저지이므로 답이 여러개가 될 수 있기 때문에 여러가지 답이 나올 수 있지만 맨처음에 나온 값을 출력해주면 된다. n=9 l=[int(input())for i in range(n)] l.sort() s=sum(l) nanjaeng=[0,0] for i in range(n): for g in range(n): if i!=g and s-100==l[i]+l[g]: nanj..

이 문제를 요약하면 N개의 수를 나열하고, 연속된 수들로 모둠을 여러 개 만든다. (1개에서 N까지 다양하게) 그때, 각 모둠끼리는 모두 직접 연결되어 있어야 하는데 그렇지 않을 경우, 부족한 개수만큼 점수가 오른다. 또 자신의 모둠이 아닌 다른 모둠과 연결되어 있을 때에도 개수만큼 점수가 오른다. 이때 점수의 최솟값을 찾는 문제이다. 이 그림으로 예를 들면, 이 그림에는 모둠이 2개가 존재하는데, 왼쪽에 있는 모둠은 내부에서 부족한 간선의 수는 3개가 되고, 오른쪽에 있는 모둠은 1개, 두 모둠을 잇는 간선 1개로, 이 그림은 5점을 가진다. 이 문제의 N의 범위는 2000 이하 이기 때문에 완전탐색은 통하지 않는다. 그럼 어떻게 풀 수 있을까? 누적 합과 dp 를 사용하면 풀 수 있다. dp [i]를..

문제를 요약하면 동그라미, 세모, 네모를 같은 모양이 연속으로 나열되도록 최소 횟수로 바꾸는 문제이다. 이문제에서 입력이 1,2,3 즉 동그라미, 세모, 네모만 존재하기 때문에 이 3개의 도형을 배치할 수 있는 경우의 수 6개를 반복문으로 탐색하면서 최소 개수를 구해주는 방식을 떠올릴 수 있다. 그다음은 어떻게 최소 개수를 구하냐 인데, 일단 두 도형을 바꿨을 때, 두 도형이 모두 최종적으로 있어야 하는 구간에 들어간다면 이 방법이 두 도형의 최소 변경 횟수가 될 것이다. 예를 들어보자. 1 3 3 2 1 1 3 2 라는 입력이 들어오고, 3 2 1 순서로 나타난다고 해보자. 그러면 최종적으로 3 3 3 2 2 1 1 1 을 만들어야 한다. 초기 입력을 숫자의 개수에 따른 구간을 나눠 보면 1 3 3 |..

요약하면 그래프가 주어지고, Q개의 쿼리에서 X, Y 가 주어지면 X, Y에서 시작하는 스패닝 트리의 최솟값을 구하라는 문제이다. 기존 스패닝 트리와는 다르게 두 점 X, Y에서 스패닝 트리가 시작할 수 있는데 이는 즉, 한 그래프 안에서 스패닝 트리가 2개가 나올 수도 있다는 소리가 된다. 그럼 이를 어떻게 해결할 수 있을까? 그 방법은 스패닝 트리의 특징을 생각해보면 알 수 있다. 스패닝 트리는 N개의 점에 대해 N-1 개의 간선을 가진다. 또 문제에선 X,Y 에서 시작하는 최소 스패닝 트리를 요구하기 때문에 N-1 간선에서 최대 1개의 간선을 제거할 수 있다. 간선을 2개 이상 제거 할 경우, 어떠한 점을 연결할 수 없게 된다. 그러므로 최대 선 1개만 지울 수 있다, 음수 가중치가 없기 때문에 선..

요약하면 i 번째 탑이 있으면 그 탑의 왼쪽에 있는 탑 중에서 i번째 탑의 높이보다 크거나 같은 높이를 가진 탑의 위치를 출력하고 없다면 0으로 출력하는 문제이다. 이 문제는 스택을 쓰면 되는 간단한 문제이다. 왼쪽부터 차례로 돌면서 스택에 있는 값들중 자신보다 작은 값들을 지워준다. 어차피 i+1 이후의 탑들 중 i번째 탑에 막힌다면 그전 탑에는 절대 도달할 수 없고, i 번째 탑보다 커도 그전 탑들은 i 번째 탑보다도 작기 때문에 쓸모가 없다. 그러므로 매 반복마다 i 번째의 탑보다 작은 높이의 탑들을 스택에서 빼주고 남은 스택의 첫 번째 탑의 위치를 구해주면 된다. 만약 스택에 들어있는 값이 없다면 0을 출력해 주면 된다. import sys from collections import deque i..

어쩌다 보니 올리게 되었다. 1번 문제 요약하면 최대값, 최소값이 변경되는 경우의 개수를 구하는 문제이다. 최소값, 최대값 변수를 초기에 설정하고 입력받은 값을 보면서 조건에 해당될때마다 더해서 값을 구해주면 된다. 시간 복잡도는 O(n) import math n=int(input()) l=list(map(int,input().split())) inf=math.inf mx=-inf mn=inf cnt=0 for i in range(n): if mxl[i]: if mn!=inf: cnt+=1 mn=l[i] print(cnt) 2번 문제 2번 문제는 문제 사진은 없지만 요약하면 한점에서 다른 점으로 이동하는데 상하좌우, 대각선으로 한번에 1씩 갈 수 있다. 이때 걸리는 최소 거리를 구하는 문제인데, 이를 봤..

문제에 쓰여있는 그대로 R를 루트노드라고 하고 LCA(U, V)를 구해주면 끝인 문제이다. 이 문제를 처음 봤을 때 LCA의 sparse table를 입력마다 갱신하는 방법이 바로 떠오르겠지만 그럴 경우 코드를 작성하지 않아도 안된다는 것을 알 수 있다. 그럼 어떻게 해야 할까 이 그림은 위 문제의 테스트케이스를 그래프로 나타낸 것이다. 이때 (U, V)에 대해 R의 위치는 1. R 이 LCA(U, V) 보다 위에 있을 때, 2. R 이 V -> LCA(U, V) 사이에 있는 노드와 연결되어 있을 때, 3. R 이 U -> LCA(U,V) 사이에 있는 노드와 연결되어있을 때, 4. R이 루트 노드를 거쳐 U, V를 가야 할 때 이렇게 총 4개가 나오게 된다. 그럼 처음부터 따져보자. 위 그림은 1번 경우..

이 문제는 여러 가지 풀이 방법이 있지만 이 글에선 유니온 파인드(줄여서 유파)를 이용한 풀이를 사용하겠다. 이 문제를 간단히 요약하면 사용할 수 있는 정점이 주어지면 한 정점에서 다른 정점으로 갈 수 있는 모든 경우의 수를 구하라는 문제이다. 이때 n개의 정점들이 이어져있다고 해보자. n개의 정점들은 자신을 제외한 모든 정점에게 갈수 있다고 할 때 이 그룹에서 나올 수 있는 경우의 수는 n*(n-1)/2 개가 된다. 이 글에선 이걸 이용할 것이다. 일단 처음에 한 정점을 기준으로 번호를 다시 부여해준다.(이 글에선 1번 정점을 기준으로 했다.) 번호를 부여할때 자신의 부모 노드의 번호를 같이 저장한 뒤 입력을 받을 때 새로 부여된 자신의 번호와 부모의 번호를 함께 저장한다. 그 뒤 자신에게 부여된 번호..
- Total
- Today
- Yesterday
- 알고리즘
- 그래프 탐색
- 깊이 우선 탐색
- 구현
- 선분 교차 판정
- discord bot
- 누적 합
- C++
- 트리
- 그래프 이론
- 그리디 알고리즘
- 자료 구조
- 느리게 갱신되는 세그먼트 트리
- 완전 탐색
- KOI
- 이분 탐색
- codeforces
- 이분매칭
- 개발
- 다이나믹 프로그래밍
- 수학
- 세그먼트 트리
- 잡봇
- 최소 스패닝 트리
- 정렬
- 트리에서의 다이나믹 프로그래밍
- 자료구조
- Python
- BOJ
- A Dance of Fire and Ice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |