백준[1671] 상어의 저녁식사
2021. 11. 18. 22:20
Algorithm/BOJ
문제 링크 http://icpc.me/1671 1671번: 상어의 저녁식사 어떤 상어는 저녁식사로 서로를 먹는다. 모든 상어는 자신과 다른 상어의 크기, 속도, 지능을 수치로 나타낸 것을 알고 있다. 만약, 상어 A의 크기, 속도, 지능이 상어 B의 크기, 속도, 지능보다 크 www.acmicpc.net 풀이 이분 매칭을 이용하여 풀 수 있다. 먹을 수 있는 상어들을 이분 매칭으로 최대 매칭을 구하면 되는데 문제는 같은 상어끼리 먹고 먹히는 경우다. 모든 수치가 같다면, 서로 먹히고 먹을 수 있는데 이 경우를 예외 처리해줘야 한다. 수치가 같은 상어들이 있다면 이미 서로 먹지 못하게 자기보다 인덱스가 작은 상어는 먹지 못하도록 한다. 코드 #include #include struct shark { int..
백준[11376] 열혈강호 2
2021. 11. 18. 17:31
Algorithm/BOJ
문제 링크 http://icpc.me/11376 11376번: 열혈강호 2 강호네 회사에는 직원이 N명이 있고, 해야할 일이 M개가 있다. 직원은 1번부터 N번까지 번호가 매겨져 있고, 일은 1번부터 M번까지 번호가 매겨져 있다. 각 직원은 최대 두 개의 일을 할 수 있고, www.acmicpc.net 풀이 이분 매칭으로 풀 수 있다. 2명과 연결을 하기 위해서 dfs함수를 두 번 호출시키면 된다. 코드 #include #include #include using namespace std; const int N = 1003; vector v[N]; bool visited[N]; int B[N]; bool dfs(int a) { visited[a] = true; for (auto b : v[a]) { if ..
백준[1017] 소수 쌍
2021. 11. 17. 15:32
Algorithm/BOJ
문제 링크 http://icpc.me/1017 1017번: 소수 쌍 지민이는 수의 리스트가 있을 때, 이를 짝지어 각 쌍의 합이 소수가 되게 하려고 한다. 예를 들어, {1, 4, 7, 10, 11, 12}가 있다고 하자. 지민이는 다음과 같이 짝지을 수 있다. 1 + 4 = 5, 7 + 10 = 17, 11 + www.acmicpc.net 풀이 이분 매칭과 에라토스테네스의 체를 이용하여 풀 수 있다. 우선 2000이하의 모든 소수를 에라토스테네스의 체를 이용하여 판별해놓는다. 그 후에 첫번째 수와 소수를 만들 수 있는 수 k를 하나 잡고 나머지 수들을 모두 소수 쌍으로 만들 수 있는 k들을 모두 구하면 된다. 나머지 수들을 모두 소수 쌍으로 만들 때 이분 매칭을 이용한다. 간선을 연결할 때는 소수 쌍을..
백준[2243] 사탕상자
2021. 11. 17. 14:31
Algorithm/BOJ
문제 링크 http://icpc.me/2243 2243번: 사탕상자 첫째 줄에 수정이가 사탕상자에 손을 댄 횟수 n(1 ≤ n ≤ 100,000)이 주어진다. 다음 n개의 줄에는 두 정수 A, B, 혹은 세 정수 A, B, C가 주어진다. A가 1인 경우는 사탕상자에서 사탕을 꺼내는 경우이 www.acmicpc.net 풀이 백준 12899 데이터 구조 이 문제와 거의 동일한 문제다. 세그먼트 트리를 이용하여 k번째 수를 빠르게 구하는 문제다. 업데이트는 일반 세그먼트 트리 업데이트와 비슷하게 하고, 쿼리를 약간 다르게 구현한다. k번째 수를 구할 때, 왼쪽 자식 노드의 값은 L이라 한다면, k L이라면 오른쪽 자식 중 k - L번째 수를 구하는 ..
백준[16927] 배열 돌리기 2
2021. 11. 16. 20:47
Algorithm/BOJ
문제 링크 http://icpc.me/16927 16927번: 배열 돌리기 2 크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2][5] www.acmicpc.net 풀이 구현 문제다. 위의 그림과 같이 돌려야 하는 수들을 미리 덱에 저장해 두고, 덱의 맨 앞에 맨 뒤의 수를 집어넣는 것을 R번 하면 된다. 그런데 이때 R이 10^9으로 매우 크기 때문에 그냥 돌리면 시간 초과가 난다. 그렇기 때문에 덱의 크기만큼 돌리면 다시 덱이 초기의 상태랑 똑같아지기 때문에 R % (덱의 크기)만..
백준[5446] 용량 부족
2021. 11. 16. 13:52
Algorithm/BOJ
문제 설명 http://icpc.me/5446 5446번: 용량 부족 팀포2 덕후 연수는 팀포2를 다운받던 도중 하드 용량이 부족하다는 것을 알았다. 이때는 침착하게 팀포2를 하지 말거나 하드를 새로 사면 되지만 불가능했고, 결국 하드에서 쓸모없는 파일을 지 www.acmicpc.net 풀이 트라이를 이용해서 풀 수 있다. 트라이에 문자열을 삽입할 때, 지워야 하는 문자열이 끝날 때, 지워야 하는 문자인지, 지우면 안 되는 문자인지를 체크하며 삽입을 한다. 그럼 어떠한 한 노드의 상황 3가지이다. 1. 지워야 하고, 지워도 되는 상황 -> 자식 노드까지 한 번에 지워버린다 2. 지우면 안 되면서, 어떤 지워야 하는 문자열의 마지막 문자인 상황 -> *없이 rm abc와 같이 지운다 3. 지워야 하지만 지..
백준[17831] 대기업 승범이네
2021. 11. 15. 18:05
Algorithm/BOJ
문제 링크 http://icpc.me/17831 17831번: 대기업 승범이네 첫 번째 줄에 판매원들의 수 N(2 ≤ N ≤ 200,000)이 주어진다. 판매원들은 1번, 2번, …, N번으로 번호가 매겨지며, 승범이는 항상 1번이다. 두 번째 줄에 2번 판매원부터 N번 판매원의 사수가 순서대 www.acmicpc.net 풀이 트리에서 dp를 통해 풀 수 있다. dp[i][0] : 노드 i가 멘티가 아닐 때, 최댓값 dp[i][1] : 노드 i가 멘티일 때, 최댓값이라 하자. dp[i][0] = max(dp[i의 자식 노드][0], dp[i의 자신노드][1] + cost[i] * cost[i의 자식노드)의 총합 (이때, 멘티는 최대 1명만 선택 가능) dp[i][1] = dp[i의 자식 노드][0]의 총..
백준[19581] 두 번째 트리의 지름
2021. 11. 15. 13:27
Algorithm/BOJ
문제 링크 http://icpc.me/19581 19581번: 두 번째 트리의 지름 트리에 N개의 정점이 있고, 각 정점 별로 1부터 N까지의 번호가 붙어있다. 트리에서 가장 먼 두 정점 간의 거리를 트리의 지름이라고 한다. 트리의 지름을 구하는 문제는 너무 많기 때문에 우리 www.acmicpc.net 풀이 bfs/dfs를 이용하여 풀 수 있다. 임의의 점을 하나 잡고, 그 점에서 가장 먼 점을 구한다. 그때 이 가장 먼 점을 a라고 하자. a에서 가장 먼 점을 구한다. 그때 이 점을 b라고 하자. 그럼 이때 a, b의 거리가 트리의 지름이 되고, 이 두 점이 트리에서 가장 먼 두 점이다. 그럼 이제 이 두 점 사이 거리를 제외한 가장 먼 거리를 찾아야하기 때문에, a에서 b를 제외한 가장 먼 거리를 ..
백준[16978] 수열과 쿼리 22
2021. 11. 13. 23:20
Algorithm/BOJ
문제 링크 http://icpc.me/16978 16978번: 수열과 쿼리 22 길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i v: Ai = v로 변경한다. 2 k i j: k번째 1번 쿼리까지 적용되었을 때, Ai, Ai+1, ..., Aj의 합을 출력한다. www.acmicpc.net 풀이 세그먼트 트리를 이용하여 풀 수 있다. 쿼리를 입력받은 순서대로 하지 않고, i번째 1번 쿼리를 하기 전에 k n; for (int i = 1; i > ipt; update(1, 0, N, ipt, i); } vector a; vector b; int t = 0; int q; cin >> q; for (int i = 0; i < q; i++) ..
백준[11375] 열혈강호
2021. 11. 13. 20:36
Algorithm/BOJ
문제 링크 http://icpc.me/11375 11375번: 열혈강호 강호네 회사에는 직원이 N명이 있고, 해야할 일이 M개가 있다. 직원은 1번부터 N번까지 번호가 매겨져 있고, 일은 1번부터 M번까지 번호가 매겨져 있다. 각 직원은 한 개의 일만 할 수 있고, 각각 www.acmicpc.net 풀이 이분 매칭 연습문제다. 백준 2188 축사배정을 풀었다면 날먹문제다. 배열 크기만 바꿔서 제출하면 맞을 수 있다. 코드 #include #include #include using namespace std; const int N = 1003; vector v[N]; bool visited[N]; // 왼쪽 집합의 i를 방문했는지 여부 int r[N]; // 오른쪽 집합의 i가 연결된 놈 bool dfs(i..
백준[2188] 축사 배정
2021. 11. 13. 20:30
Algorithm/BOJ
문제 링크 http://icpc.me/2188 2188번: 축사 배정 농부 존은 소 축사를 완성하였다. 축사 환경을 쾌적하게 유지하기 위해서, 존은 축사를 M개의 칸으로 구분하고, 한 칸에는 최대 한 마리의 소만 들어가게 계획했다. 첫 주에는 소를 임의 배정해 www.acmicpc.net 풀이 이분매칭 연습문제다. 이분 매칭에 대한 설명은 여기를 참고해라. 코드 #include #include #include using namespace std; const int N = 202; vector v[N]; bool visited[N]; // 왼쪽 집합의 i를 방문했는지 여부 int l[N]; // 왼쪽 집합의 i가 연결된 놈 int r[N]; // 오른쪽 집합의 i가 연결된 놈 bool dfs(int a) ..
백준[2296] 건물짓기
2021. 11. 13. 16:31
Algorithm/BOJ
문제 링크 http://icpc.me/2296 2296번: 건물짓기 첫째 줄에 건물의 개수를 나타내는 자연수 N(1 ≤ N ≤ 1,000)이 주어진다. 다음 N개의 줄에는 건물을 지을 x, y(1 ≤ x, y ≤ 1,000,000,000) 좌표와 그 건물을 지었을 때의 이익 c(1 ≤ c ≤ 50,000)가 주어진 www.acmicpc.net 풀이 dp로 풀 수 있다. dp[i][0] = i번째까지 1,3 사분면을 사용하여 최댓값, dp[i][1] = i번째까지 2, 4 사분면을 사용하여 최댓값 위의 정의대로 구현하면 된다. 코드 #include #include using namespace std; struct T { int x, y, c; }; vector v; int dp[1003][2]; int m..
백준[1011] Fly me to the Alpha Centauri
2021. 11. 12. 23:53
Algorithm/BOJ
문제 링크 http://icpc.me/1011 1011번: Fly me to the Alpha Centauri 우현이는 어린 시절, 지구 외의 다른 행성에서도 인류들이 살아갈 수 있는 미래가 오리라 믿었다. 그리고 그가 지구라는 세상에 발을 내려 놓은 지 23년이 지난 지금, 세계 최연소 ASNA 우주 비행 www.acmicpc.net 풀이 규칙을 찾으면 되는 문제다. 어떤 거리만큼 가장 짧은 거리로 가려면 한 번에 많은 거리를 움직여야 한다. 한 번에 움직이는 거리가 최대가 되는 상황을 잘 구하면 된다. 만약 한번에 k만큼 움직인다면, k만큼 움직이기 위해서는 1 2 3 4 .. k k-1 k-2 .. 1 이런 식으로 움직여야 할 것이다. 이때 1 + 2 + 3 + 4 + .. + k + k-1 + k..
백준[2631] 줄세우기
2021. 11. 12. 16:39
Algorithm/BOJ
문제 링크 http://icpc.me/2631 2631번: 줄세우기 KOI 어린이집에는 N명의 아이들이 있다. 오늘은 소풍을 가는 날이다. 선생님은 1번부터 N번까지 번호가 적혀있는 번호표를 아이들의 가슴에 붙여주었다. 선생님은 아이들을 효과적으로 보호하기 www.acmicpc.net 풀이 LIS(Longest Increasing Subsequence)를 이용하여 풀 수 있다. 가장 긴 증가하는 부분 집합을 구하고, 그 부분 집합에 속하지 않는 사람들만 이동하면 되기 때문에 n - LIS를 하면 된다. 코드 #include #include using namespace std; int arr[202], dp[202]; int ret = 0; int main() { ios::sync_with_stdio(0)..
백준[16946] 벽 부수고 이동하기 4
2021. 11. 12. 02:10
Algorithm/BOJ
문제 링크 http://icpc.me/16946 16946번: 벽 부수고 이동하기 4 N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 한 칸에서 다른 칸으로 이동하려면, 두 칸이 인접해야 한다. 두 칸이 www.acmicpc.net 풀이 dfs를 이용하여 풀 수 있다. 모든 1에 대해서 dfs를 돌며 인접한 0이 몇 개인지 센다면 한번 dfs를 돌 때 O(NM)이고 dfs를 NM번 돌릴 수 있기 때문에 O(N^2M^2)이 돼서 시간이 터질 것이다. 그렇기 때문에 인접한 0의 개수들을 미리 구해놓고, 1이 나올 때 상하좌우에 붙어있는 인접한 0의 개수만 세주면 된다. 상하좌우에 붙어있는 그룹이 같은 그룹인지 아닌지 체크도 ..