본문 바로가기

알고리즘/백준

(109)
[BOJ 1062] 가르침(시간초과, C++, 40% 틀린이유) 이 문제는 브루트포스 탐색을 통해서 문제를 해결하면 된다. 처음에, 문제를 풀었을 때는 시간초과가 발생했다. 문제의 조건을 살펴보면, "남극언어의 모든 단어는 "anta"로 시작되고, "tica"로 끝난다." 라는 표현이 있다. 이 말의 뜻은, a, n, t, i, c은 무조건 가르쳐야 한다는 것을 의미한다. 만약에, a, n, t, i, c의 문자를 브루트포스 탐색에서 선택 및 제외(조합)할 수 있도록 한다면 시간초과가 발생한다. 이제는 40%대의 실패에 대해서 말씀드리려고 한다. 개인적으로 처음에 문제를 좀 더 효율적으로 풀기 위해서, anta[*]tica, [*]에 해당하는 문자열들의 알파벳들을 모두 확인해서, 이 알파벳들을 배워야하는 문자들이라고 정의하자. 배워야하는 문자들 > K인 조건을 만족하..
[BOJ 1541] 잃어버린 괄호 여기서 주목해야 할 점은, 두 연산자가 반복해서 나오지 않는다는 것이다. 즉, 교대로 연산자가 나타나게 된다. 만약에 처음 연산자가 + 라면, a + b - c + d - e + f, 여기서 최소의 값을 얻으려면, a + b - (c + d) - (e + f) 형태로 괄호를 치면되고, 즉 b말고 c, d, e, f는 모두 빼주면 된다는 것이다. 나머지 경우인 처음 연산자가 - 라면, a - b + c - d + e - f a - (b + c) - (d + e) - f a를 제외하고 나머지 b, c, d, e, f에 대해서 모두 빼주면 된다. 이 문제가 그리디인 이유는, 모든 경우를 보지 않고 +를 먼저 계산하게끔 괄호를 치면 정답을 구할 수 있기 때문이다. 해설코드(C++). 1 2 3 4 5 6 7 8..
[BOJ 2533] 사회망 서비스(SNS) 이 문제는 풀지 못해서, 구글링을 통해서 문제를 해결했다. 문제에 명시적으로 나타나지 않은 부분이 있다면, Root는 항상 1번으로 표현된다는 것이다. 위의 그림을 통해서, Root Node가 1번이라는 것을 표현해주고 싶었다고 생각하면 그럴듯하다... 무튼, Root가 1번이므로, 주어진 관계를 이용해서, 트리구조로 변형해야 한다. 어떤 노드들을 선택해야 최소의 얼리어답터를 구할지 모르기 때문에, 전체탐색이 필요하다. 전체 탐색을 할 때, 메모이제이션을 통해서 DP를 사용할 것이다. DP[i][j] = i번째 Node, 얼리어답터의 유무(j)에 대한 최소 선택 얼리어답터 수 을 식으로 사용할 것이다. 현재 노드가 얼리어답터인지 아닌지에 따라서, 호출되어야 할 함수가 다르다. 추가적으로 참고해야 할 사항..
[BOJ 2503] 숫자 야구 https://www.acmicpc.net/problem/2503 2503번: 숫자 야구 첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트�� www.acmicpc.net 이 문제는, 예전 인턴할 때 4자리 야구를 풀어본 기억이 있다. 숫자 야구는 워낙 유명한 게임이니 자세한 설명은 생략하겠다. 여기서 핵심은, 민혁이가 물어본 숫자를 가지고 어떻게 이용할 것인지가 핵심이다. 민혁이가 물어본 숫자는 오답일 것이다. (3S는 안줄것이니) 그 오답의 스트라이크 횟수와 볼의 횟수에 주목해야 하는데, 어떤 후보 숫자 중에서, 그 오답과 동일한 스트라이크 횟수와 볼의 횟수..
[BOJ 10448] 유레카 이론 어떤 수가, 최대 3개 중복 허용인 삼각수의 합으로 표현되는지 알아봐야 한다. 그러기 위해서는, 전체 탐색을 하거나 삼각수의 합으로 표현되는지 확인하는 신기한 방법을 찾아야 하는데... 이 문제의 경우, 자연수의 범위가 1000까지 이므로, 전체 탐색을 해도 시간복잡도가 크지 않다. 전체탐색으로 문제를 풀기로 결정하면, 삼각수의 합이 1000이하인 값들을 구해놓고, 3중포문을 통해서, 만들 수 있는 값들을 모두 체크하면 된다. 해설코드(C++). 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 32 33 34 35 36 37 38 #include #include #include using namespac..
[BOJ 10610] 30 (배수판정법 참고) 30의 배수가 되기 위한 조건을 찾아야 하는데, 쉽지 않아서 구글링을 했다. 3의 배수들의 공통점은 각 자리수의 합이 항상 3의 배수를 이룬다는 것이다. 3 * 78 = 234 2 + 3 + 4 = 9 4의 배수나, 7의 배수는 그렇지 못한데 신기하게 3의 배수는 위의 특징이 있다. 1 ~ 10의 배수들은 모두 배수판정법이 있더라. 배수판정법을 Divisibilty Rules이라고 부른다. 유사한 문제가 나오면, 이 자료를 바탕으로 문제를 해결하면 될 거 같다. 수학적 기본 지식이 필요한 문제다. 30의 배수는, 3의 배수와 10의 배수의 특징을 가지면 된다. 가장 큰 수는, 모든 문자를 넣은 다음에 정렬한 후 출력하면 된다. 해설코드(C++). 1 2 3 4 5 6 7 8 9 10 11 12 13 14..
[BOJ 2217] 로프 그리디 알고리즘 분류로 되어있는데, 정확한 분류 사유는 모르겠다. 이 문제를 풀기 위해서는 w의 물건을 들기 위해서 k개의 로프를 사용했다면, 각 로프에 w/k의 하중이 걸린다. 로프마다 견딜 수 있는 무게를 오름차순으로 정렬했다고 하면, (각 로프가 견딜 수 있는 최대 하중) * (사용할 수 있는 로프의 개수)로 최댓값을 찾으면 된다. 해설코드(C++). 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 #include #include #include using namespace std; long long N, val; long long sum = 0; vector v; int main() { cin >> N; for(int i = 0..
[BOJ 2602] 돌다리 건너기 두루마리에 있는 문자열을 기반으로, 천사 혹은 악마의 돌다리를 건너야 한다. 전체적인 탐색이 필요하고, 탐색에서 중복으로 나타나는 유형은 메모이제이션이 필요하다. 메모이제이션을 위해서, 사용할 변수는 다음과 같다. 1. 천사 돌다리의 인덱스 2. 악마 돌다리의 인덱스 3. 두루마리 문자열의 인덱스 4. 다음 건너야 할 돌다리 이 4가지 변수는 메모이제이션에 있어서 꼭 필요한 것이다. 하나라도 누락된다면, 올바른 값이 다른 값으로 덮어씌워질 수 있다. 전체적인 탐색은, 두루마리의 문자열을 기반으로만 확인해주면 된다. 중요한 것은, 돌다리를 하나 이상 건널 수 있다는 것을 유의해서 코드를 작성해야 한다. 해설코드(C++). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19..