-
[BOJ] 2842 : 집배원 한상덕
2842 : 집배원 한상덕 풀이 parametric search로도 풀릴 것 같은데 나는 투포인터로 풀었다. 높이가 될 수 있는 후보는 1000000개이지만 주어지는 그리드의 크기가 50*50이 최대이므로 많아야 2500개 후보가 있을 수 있다. 주어진 높이들을 정렬한 다음, 투포인터로 구간을 잡아 dfs를 돌려주자. 코드 #include <cstdio> #include <vector> #include <cstring> #include <algorithm> using namespace std; const int dx[] = { 0,0,-1,1,-1,-1,1,1 }; const int dy[] = { -1,1,0,0,-1,1,-1,1 }; int n, sx, sy, k, b[55][55], chk[55][55]; char a[55][55]; vector<int>...
-
[codeforces] 1073C : Vasya and Robot
1073C : Vasya and Robot 풀이 널 향한 내 사랑은 여기까진가 봐. 그 사람 곁에서 행복하길 바라. 코드 #include <cstdio> int n, ex, ey, x[200002], y[200002]; char s[200002]; int abs(int x) { return x < 0 ? -x : x; } void f(char c, int &x, int &y) { if (c == 'U') y++; if (c == 'D') y--; if (c == 'L') x--; if (c == 'R') x++; } int main() { scanf("%d %s...
-
[BOJ] 8101 : Rods
8101 : Rods 풀이 요약: 양 끝점이 고정된 길이 L의 선분이 있다. 이 선분의 가운데를 이쁘게 늘려서 길이 L+d의 곡선을 만든다. 그럼 길이 L의 현과 길이 L+d의 호가 만들어진다. 이 때, 현의 중심과 호의 중심까지의 거리 x는 얼마일까? 알고리즘에 수학을 싸서 드셔보세요!! 주어진 호를 예쁘게 연장해서 예쁜 원을 만들어주자. 원의 중심에서 현의 끝점까지 예쁜 반지름 r1, r2도 그어주자. 현을 이등분하는 예쁜 반지름 r3도 그어주자. r3와 r2, r3와 r1 사이의 각을 세타라고 하자. 삼각함수를 이용해서 식을...
-
[BOJ] 6209 : 제자리 멀리뛰기
6209 : 제자리 멀리뛰기 풀이 이분탐색을 해주자 mid를 최소로 뛰는 거리로 두고 파라메트릭 해주자. 코드 #include <cstdio> #include <algorithm> using namespace std; int d, n, m, a[50005]; int main() { scanf("%d %d %d", &d, &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); a[n + 1] = d; sort(a + 1, a + n + 1); int lft = 0, rgt = d, ans; while (lft <= rgt) { int mid...
-
[교육용] 이분 탐색
안녕하세요! 이번 포스트에서는 binary search에 대해 이야기 해보겠습니다. binary search, 이분 탐색은 어떤 정렬된 범위 내에서 우리가 원하는 값을 빠르게 찾기 위한 탐색 방식입니다. 예시 문제 https://www.acmicpc.net/problem/1920 수 찾기 n개의 정수열 중에 어떤 숫자 X가 존재하는지 판단하는 문제입니다. 평범하게 구현했을 때, X가 존재하지 않는 최악의 경우 n개의 모든 숫자를 돌아보아야 하므로 시작복잡도는 O(n)이 됩니다. 하지만 이분 탐색을 이용하면 O(n)을 O(log n)으로 줄일 수 있습니다. 이게 얼마나 빨라진 거냐면, 2^100번 돌아야하는 작업을 100번만 돌아서 끝낼 수...
-
[codeforces] #403 div2 B
#403 div2 B. The Meeting Place Cannot Be Changed 풀이 코포 문제는 처음 풀이한다! (두근두근) 이분 탐색을 돌리면 쉽게 해결할 수 있다. 만나는 시간을 mid로 두면, n*log(최대차이)이므로 제한시간에 맞게 돌릴 수 있다. 각각의 좌표 x[i]를 돌면서 mid에 갈 수 있는 max_left, min_right를 구한다. max_left <= min_right면 mid에 만날 수 있다. 왜 그런지는 그림판에 대충 선 몇 개 그려보면 직관적으로 이해 될 것이다. (아마?) AC 받긴 했는데 저렇게 짜도 실수 오차 안 나는지는 모르겠다 (…) 코드...
-
[BOJ] 1300 : K번째 수
1300 : K번째 수 풀이 임의의 숫자 m을 골라서 K번째 숫자인지 판단해보자! 그 임의의 숫자 m은 무려 O(log K)에! 무려 이분 탐색으로 찾아보자! 그렇다면 떠오르는 질문, m 보다 작은 숫자의 개수를 어떻게 하면 빠르게 구할 수 있을까? A[i][j]에서, i행에 속한 숫자들은 i*j이므로 모두 i의 배수이다. 그러므로 min(mid/i, N)이 i번째 행에서 mid보다 작은(= 임의의 m보다 작은) 숫자들의 개수가 된다. eg. N = 1000인 경우, 첫 mid가 1000*1000/2 = 50만이 되는데, 50만/i가 N을 넘어갈 수 있으므로 min(mid/i,...
-
[BOJ] 14434 : 놀이기구1
14434 : 놀이기구1 풀이 머그컵 문제! parallel binary search를 사용하면 된다! 자세한 풀이는 여기에 있다. 헤헤 놀이기구2도 풀어봐야지 코드 #include <stdio.h> #include <algorithm> #include <vector> using namespace std; const int MAX = 2e5 + 3; int N, M, K, Q; int lim[MAX], ans[MAX]; vector<int> grow[MAX]; inline int get_sum(int u, int v, int k) { int ret1 = upper_bound(grow[u].begin(), grow[u].end(), k) - grow[u].begin(); int ret2 = upper_bound(grow[v].begin(), grow[v].end(), k) - grow[v].begin(); return ret1 + ret2; }...
-
[BOJ] 13209 : 검역소
13209 : 검역소 풀이 이분 탐색(log n)을 돌면서 그리디(n)을 돌리면 O(n log n)에 해결할 수 있다. priority_queue를 사용하기 전에 벡터를 써서 정렬하는 생각을 먼저 했지만 코딩이 괴랄해져서 포기하고 우선순위큐를 사용했다. 바이너리 서치의 mid를 비축할 백신의 수라고 두고, 주어진 검역소만으로 mid를 충족시킬 수 있는지 그리디로 풀면 된다. 싸이클이 없고 임의의 a에서 b로 가는 경로가 단 하나이기 때문에 그리디로 풀 수 있다! dfs의 리턴값은 항상 mid를 넘지 않음이 보장된다. 물론 인구수가 mid를 넘을 수는 있다. 그건 left...