반응형

알고리즘/boj 49

BOJ 1967 트리의 지름

문제를 보고 몇시간 정도 풀이를 생각해보다가 도저히 떠오르지 않아 다른 사람 풀이를 참고하여 아이디어를 얻었다. 문제에 간선의 가중치는 100보다 크지 않는 양의 정수라고 하여 특정 노드에서 가장 깊이 들어가야 최소한 최대 길이가 될것 같다는 생각을 하였다. DFS를 생각한것이다. 하지만 DFS 한번만으로 도저히 답을 찾아낼 수 없었다. 풀이를 보니 DFS를 두번 사용 해야 한다고 하였다. 왜 DFS를 두번 사용해야 하는지 이해가 안되다가 다음과 같은 특징을 이해한 다음에 문제를 해결할 수 있었다. 하나의 정점에서 가장 멀리 있는 정점은 원의 지름 부분에 해당하는 정점이다. 즉 어느 점에서 DFS를 통해 가장 긴 점을 찾으면 그 점은 가장 지름이 긴 원의 시작 점이 된다. 이후 그 시작점에서 또 가장 긴..

알고리즘/boj 2022.12.29

BOJ 1920 수 찾기

N개의 수 중에서 M 개의 수가 존재하는지 여부를 0,1로 출력하는 문제이다. 총 M 개의 수가 N에 존재 하는지 알기 위해서 브루트포스 알고리즘을 사용한다면 N*M 즉 10000000000으로 시간초과가 발생한다. 때문에 이분탐색으로 logN 의 시간복잡도를 활용하여 문제를 풀어야 한다. 입력 N은 정렬되어 들어오지 않기 때문에 이분탐색을 위해 정렬이 필요하다. 처음에 STL algorithm에 있는 sort를 활용하여 정렬하였는데 제출하고 나니 시간초과가 발생하였다. 원인이 뭔지 찾아보다가 어떤 사람은 qsort를 직접 구현하면 된다고 하는데, 실제 qsort는 STL에서 제공하는 sort보다 시간이 느리다. 한참 찾아보다가 발견한 원인은 재귀함수 파라미터에 vector를 call by referen..

알고리즘/boj 2022.12.28

BOJ 2468 안전 영역

물의 높이가 0~100 까지 변하는 동안 각 높이마다 잠기지 않는 안전한 영역이 존재한다. 문제 해결 방법은 각 높이에서 안전한 영역의 최대 갯수를 구하는 것이다. 안전한 영역 즉 섬의 갯수를 구하기 위해서 물의 높이보다 높은 영역을 기준으로 DFS를 적용하였다. 핵심은 방문한 영역을 표시 하고 한번 방문한 영역은 DFS에서 제외시켜야 한다. #include #include #include using namespace std; int n; int map[102][102]; bool visit[102][102]; int dx[4] = { 0,1,0,-1 }; int dy[4] = { 1,0,-1,0 }; void dfs(int x, int y, int height) { if(visit[x][y]) { re..

알고리즘/boj 2022.12.27

BOJ 13549 숨바꼭질 3

처음 떠오른 방법은 queue에다가 각 인접 노드를 {노드,가중치 합} 로 저장하고 큐를 순회하면서 해당 노드의 가중치 합을 최소로 만들어 주는 것이였다. 즉 BFS 방식을 떠올린 것이다. 하지만 이 문제를 BFS로 풀려면 큐에서 가중치가 0인 노드부터 방문해야 하는 조건이 붙는다. 위에 조건을 적용하지 않아 제출하면 자꾸 8%에서 틀렸다고 나왔다..... BFS로 해결되지 않아 다익스트라를 적용하였다. 다익스트라가 적용될 수 있는 이유는 "가중치가 모두 0 또는 양수이고, 특정 지점 a에서 b 지점까지의 최단 경로 가중치"를 구하는 것이므로 다익스트라 알고리즘을 적용할 수 있다. 하지만 기존 다익스트라와 조금 다른점은 인접노드에 대한 정의가 나와있지 않기 때문에 각 지점에서 인접한 노드를 X+1, X-..

알고리즘/boj 2022.12.27

BOJ 1976 여행 가자

문제에서 여행 계획에 속한 도시 M이 주어지고 총 N 개의 여행 계획이 주어진다. 이때 여행계획을 달성할 수 있는지 없는지 확인하는 문제이다. 문제를 해결하기 위해 생각해낸 아이디어는 다음과 같다. 1. 만약 a-b-d-a-c 순서로 여행한다고 가정하였을경우 a-b, b-d, d-a, a-c 가 연결 되어있다면 무조건 갈수 있지 않을까? 2. 그럼 서로 연결되어있다는 것은 어떻게 알수 있을까? -> union - find를 활용하자!! Union - Find에서 핵심은 각각의 i,j에 대해 각각 root parent를 확인하고 둘중에 더 큰 집합으로 parent를 업데이트 해준다. 이렇게 구한 그래프와 그의 parent 정보를 바탕으로 계획에 있는 도시들이 모두 같은 root parent를 가질경우 여행..

알고리즘/boj 2022.12.24

BOJ 18352 특정 거리의 도시 찾기

이 문제의 특징은 특정 도시에서 출발하여 최단거리가 정확히 k 인 모든 도시를 출력하는것이다. (단 k인 도시가 존재하지 않은면 -1을 출력한다.) 문제를 읽으면서 최단거리 키워드가 나와 BFS응용 이라는 것을 알게 되었다. 하지만 기존에 내가 풀던 BFS문제는 상,하,좌,우로 이동하는 문제를 주로 풀었다. 비슷한 로직으로 접근하여 각 노드의 간선을 인접리스트로 구현하였고, x노드를 시작으로 갈수 있는 경로를 인접리스트를 순회하면서 탐색하였다. 핵심은 인접리스트 순회시 visited 표시를 하는것이다!!! 순회시 visited를 표시하지 않고 queue에서 pop 할때 visited를 표시해준다면 최단경로를 구할수 없다. 위의 그래프를 인접리스트를 순회할때 queue에 들어가는 값은 다음과 같다 {nod..

알고리즘/boj 2022.12.24

BOJ 1946 신입 사원

문제에서 '최고만을 지향하는' 이라는 힌트를 통해 그리디(Greedy) 알고리즘을 사용하는 것을 유추할 수 있다. 따라서 서류심사 성적, 면접 성적 순위중 하나를 잡아 1등부터 나열한후 첫번째 부터 선택을 해 나간다. 예를 들어 서류 심사 기준으로 정렬했다고 가정해보자. 테스트 케이스를 정렬하였을 경우 각각 다음과 같이 된다. a b //a=서류 b=면접 1 4 2 3 3 2 4 1 5 5 a b //a=서류 b=면접 1 4 2 5 3 6 4 2 5 7 6 1 7 3 이미 서류 기준으로 정렬 하였기 때문에 A지원자 (1 4) 와 B지원자 (2 3) 을 비교하면 B지원자는 무조건 A지원자의 면접 순위보다 높아야 합격 할 수 있다. 즉 위의 정렬한 예시에서는 이후 지원자가 이전 지원자의 면접 최고 순위 보다..

알고리즘/boj 2022.11.10

BOJ 1931번 회의실 배정

하나의 회의실을 여러 회의가 사용하는데 각각의 시작 시간과 끝나는 시간이 주어진다. 회의를 잘 스케쥴링 하여 회의실을 사용할때 최대 몇개의 회의가 회의실을 사용할수 있는지 구하는 문제이다. 처음에 어렵게 꼬아 생각하여 시작 시간이 빠른 순서대로 정렬하고 끝나는 시간이 빠른 순서대로 정렬하여 두개를 어떻게 지지고 볶아 비교하려고 하였다.(생각해보면 다음 회의 시작 가능 여부는 이전 회의의 종료 시간에 따라 결정된다.) 따라서 끝나는 시간을 기준으로 정렬 하여 제일 일찍 끝나는 회의를 기준으로 다음 회의 시작 시간을 결정하면 된다. 한편 문제에서 한 회의가 끝나는 것과 동시에 다음 회의가 시작될 수 있다. 회의 시작시간과 끝나는 시간이 같을 수도 있다. 라고 주어졌기 때문에 다음과 같은 반례가 생길 수 있다..

알고리즘/boj 2022.11.08

BOJ 11399번 ATM

문제를 읽어보면 OS 스케쥴링에서 SJF 알고리즘인것을 확인할 수 있다. 기존 1번 방식으로 모든 사람이 돈을 인출하는데 걸리는 wating time은 FIFO 스케쥴링에 의해 39 분을 기다려야 한다. 반면 SJF 는 가중치(P)가 가장 작은 순서 우선으로 처리한다. n=[2,5,1,4,3] p=[1,2,3,3,4] 일때 일을 끝내는데 걸리는 시간은 다음과 같다 2= 1 5= 1+2 1= 1+2+3 4= 1+2+3+3 5= 1+2+3+3+4 위의 결과를 다 더하는것이 답이므로 다음과 같은 식을 구할 수 있다. i=n result += i*p[n-i] #include #include #include using namespace std; int main() { ios_base::sync_with_stdio..

알고리즘/boj 2022.11.08
1 2 3 4 5
반응형