본문 바로가기

전체 글

(147)
백준 9359: 서로소 https://www.acmicpc.net/problem/9359 간단화이 문제는 누적 합을 푸는 요령으로 비슷하게 해결할 수 있다는 것은 금방 알았다.f(x, n) = 1~x 사이에 n과 서로소의 갯수라 정의 하면f(B, N) - f(A - 1, N)으로 간단화할 수 있다. 문제는 어떻게 f(x, n)을 구할 수 있을까다. 소인수분해이것을 구하기 위해서 서로소의 정의를 다시 기억해보자.서로소는 두 정수를 나눌 수 있는 양의 정수가 1밖에 없을 때를 서로소라한다.이 말은 즉, 약수를 공유하지 않는다는 것이다. 그러면, 1 ~ X사이에 특정 수를 약수로써 가진 수는 몇개일까?예를 들어, 2라면? 2, 4, 6, 8, 10 ... 3이라면? 3, 6, 9, 12, 15 ...즉, 특정 약수를 D라 정의했을 ..
백준 1044: 팀 선발 https://www.acmicpc.net/problem/1044 중간에서 만나기푼 보람이 있었던 재밌는 문제였지만, 한편으론 이번에도 사소한 실수로 시간을 낭비해서 그것이 다소 퇴색된 것이 아쉽다. N이 2보다 크고, 36보다 작거나 같은 자연수고, 배열의 원소가 들어갈 지 말지를 결정하는 문제이기에, "중간에서 만나기" 알고리즘을 사용하면 될 것 같다. 일단 이전에 풀었던 관련 알고리즘 문제를 다시 보며, 코드를 분석했다.https://www.acmicpc.net/problem/1208#include #include #include using namespace std;using ll = long long;vector arr1, arr2, s1, s2;int N, S, num;ll ans = 0;voi..
백준 2258: 정육점 https://www.acmicpc.net/problem/2258 이 문제는 얼핏 보면, 가격 순으로 정렬한 뒤에, 앞에서부터 무게를 더했을 때, M을 넘었을 경우 해당 가격이 정답인것처럼 보인다. 그렇게 생각했던 나였지만, 정답률이 낮은 편은 17%인 것을 보니 이것만으로 해결할 수 없을 것 같았다.혹시 이것만으로 해결 못할 케이스가 있을까? 그렇다, 고기의 가격이 같을 경우 위의 아이디어론 해결못한다.예시를 들자면,3 1001 150 250 2이 예제의 답은 4이지만, 위의 아이디어론 2가 나온다. 따라서 가격이 같은 경우를 따로 생각해야한다.그럼, 어떻게 처리해야 할까? 기존 아이디어인 무게를 더하는 것 까지 동일하게 진행하자,해당 가격보다 큰 고기를 살 때, 그 가격보다 작은 고기는 얼마든지 덤으..
백준 15807: *빛*영*우* https://www.acmicpc.net/problem/15807 이 문제는 여러가지 풀이 방법이 있다. 누적 합을 이용하는 법, DP를 사용하는 법, 세그먼트 트리를 활용하는 법 등여기서 나는 이 문제를 DP를 사용해서 풀었다. 하지만 사소한 실수로 너무 먼 길을 돌아왔다.우선 풀이에 대해 이야기하자.특정 위치에서 빛의 세기를 구할려면, 다음과 그림안에 몇 개의 라이트가 있는지 구하면 된다.그럼 바로 위에 위치한 좌표의 빛의 세기를 구할려면 어떻게 해야할까?파란 색으로 표시된 구역의 라이트 갯수를 구해야한다. 하지만, 일일히 해당 위치의 라이트 갯수를 세는 것은 시간초과가 날 것이 뻔하다. 그렇다면, 다른 곳에서 파란색 위치의 라이트 갯수를 다른 곳에 구할 수 없을까?구할 수 있다. 빨간색은 왼쪽 아..
백준 5624: 좋은 수 https://www.acmicpc.net/problem/5624 이 문제는 지금 생각해보면 그렇게 어려운 문제가 아니다. 하지만, 너무 한가지에 집중해서, 문제 해결법을 제대로 떠오르지 않아서 아쉽다. 내가 DP 문제를 풀 때엔 일단 가고, 그 선택한 상태를 DP하는 방식으로 해결한다.만약 내가 평소 DP 문제를 해결하는 방식으로 이 문제를 해결한다면DP[현재 인덱스][합][숫자 카운트]이런 방식으로 문제를 해결했을 것이다. 그런데, 이 문제에서 -100,000  Meet in the middle 방식과 유사하게, 두 개의 포인터를 활용하면, 구할 수 있을 거란 막연한 아이디어가 떠오르긴 했지만, 그것의 구현 방법을 잘 몰랐다. 결국 구글링을 거치게 된다.https://cat-holic0713.tist..
백준 2024: 선분 덮기 https://www.acmicpc.net/problem/2024 스위핑의 방법이 문제는 꽤 고민을 하였다.정렬을 한 뒤, 스위핑을 하면 될 것 같은데 스위핑을 어떻게 해야할지가 문제였다.단순히 스위핑을 하면 [0, M]을 덮는 최소의 선분 갯수를 구할 수 없어서 특수한 방법이 필요할 것 같다. 일단 나는 이 문제를 해결하기 위해서, 예시 하나를 만들었다. 10-1 53 74 100 0답: 2 이 문제를 근본적으로 해결할 수 있는 예시라 생각했기 때문이다. 여러 시도이렇게 생각을 하니, 우선 선분을 왼쪽 끝 순서대로 sort한 뒤에, 순서대로 오른쪽 끝을 우선순위 큐에 저장해서 현재 선분과 왼쪽 끝과 맞닿는 최소의 오른쪽 끝을 구하면 어떨까? 란 생각을 했었다. 위의 예시 위주로 생각해낸 방법이였고, 혹..
백준 2923: 숫자 게임 https://www.acmicpc.net/problem/2923 어떻게 해결하지?모든 A와 모든 B를 짝지어야하기 때문에 가장 큰 수는 가장 작은 수와 매칭해야 최댓값의 최솟값을 구할 수 있을 것 같다.왜냐하면 모든 수를 짝지을 때, 가장 큰 수는 최대한 덜 더하는 것이 이득이기 때문이다. 즉, 다음과 같이 수가 주어졌다면.A: 1 3 5 7 9 B: 2 5 8 11 14(1, 14) (3, 11), (5, 8), (5, 7), (2, 9) 이렇게 매칭한 뒤에, 이 중 합이 가장 큰 15를 고르면 그것이 정답일 것이다. 문제는 라운드마다 수를 더할 때마다. 정렬된 상태의 array가 필요하다. 라운드마다 정렬 시, 시간복잡도는 O(N * N * log(N))N=100,000 라서 시간초과는 불보듯 뻔하..
백준 2283: 구간 자르기 https://www.acmicpc.net/problem/2283 이 문제는 풀이법이 재미있어서 다뤄보려한다.해결을 위해서 누적 합과 투 포인터란 다소 생소한 조합을 사용해야하는 것이 흥미로웠다. 큰 그림은 다음과 같다.왼쪽 끝 점과 오른쪽 끝 점을 두고, 그 사이의 선분의 길이가 K보다 작으면 오른쪽 끝점을 오른쪽으로 옮기면서 해당 위치에 있는 선분의 길이를 더하고, K보다 크다면 왼쪽 끝점을 오른쪽 옮기면서 이전 위치에 있던 선분의 길이를 뺀다.기본적인 투 포인터 사용법이다. 여기서 해당 위치의 "선분의 길이"는 해당 위치의 "선분의 갯수"와 같다고 봐도 무방하다. 그렇다면 여기서 특정 위치의 선분의 갯수는 어떻게 구해야할까?N = 1,000이고, 양 끝점 위치의 최대가 1,000,000인 만큼 단순..