본문 바로가기

전체 글

(201)
[BOJ 1213] 팰린드롬 만들기(브루트 포스 접근이 필요한가?) 팰린드롬은 알고리즘의 단골 소재이다. 이번 문제는, 팰린드롬을 만들어야 하는 문제이다. 팰린드롬은, 문자열를 뒤집어도 같은 문자열이 되어야 한다. 주어진 문자열을 통해서, 각 대문자 알파벳의 개수를 파악하고 짝수냐 홀수에 따라서 문자열을 처리해주면 된다. 팰린드롬이 불가능한 경우는, 홀수인 알파벳이 1개 초과되면 팰린드롬이 불가능하게 된다. 위의 말들을 바탕으로 코드를 구현하면 아래와 같다. 해설코드(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 39 40 #include #include using namespace std; int arr[26] = { ..
[BOJ 1946] 신입사원 이 문제는 브루트포스로 비교하게 되면, 시간 초과가 발생한다. 그리고, 이 문제의 분류도 그리디 알고리즘이므로 더더욱 브루트포스는 아닐 것이다. 문제에서 원하는 것은, "그래서 진영 주식회사는, 다른 모든 지원자와 비교했을 때 서류심사 성적과 면접시험 성적 중 적어도 하나가 다른 지원자보다 떨어지지 않는 자만 선발한다는 원칙을 세웠다. 즉, 어떤 지원자 A의 성적이 다른 어떤 지원자 B의 성적에 비해 서류 심사 결과와 면접 성적이 모두 떨어진다면 A는 결코 선발되지 않는다." 을 만족하는, 신입사원의 수이다. 서류심사를 기준으로 지원자들을 정렬하면, 특정 지원자가 합격하기 위해서는, 자기의 서류심사점수보다 높은 지원자들을 대상으로 면접 시험 성적이 높아야 한다. 정렬을 하고, 브루트 포스로 비교를 하면 ..
[BOJ 7453] 합이 0인 네 정수 4개의 배열을 가지고, 합이 0이 되도록 구성해야 한다. 이 문제를 브루트포스로 풀게 되면, 배열의 크기는 최대 4000이므로, 4000의 4승이 된다. 시간복잡도가 너무 크므로, 분명히 시간초과가 발생한다. 시간초과가 발생하지 않기 위해서는, 두 개의 배열의 합의 모든 값을 vector 자료구조에 넣는다. 자료구조에 넣은 다음에 정렬을 시킨다. 그리고, 남은 두 개의 배열의 합과 vector의 원소를 합쳤을 때, 0이 되는 값을 찾으면 된다. vector에 값을 넣은 이유는 0이 되는 값을 찾을 때, 이분탐색(logN)을 하기 위해서이다. 이렇게 하면, 시간 복잡도는 4000 * 4000 * log(4000 * 4000)으로 줄어드므로 시간초과가 발생하지 않는다. 해설코드(C++). 1 2 3 4 5 ..
유용한 내장 함수 추천(C++, 알고리즘, 백준) vector와 관련해서 내장 함수들을 매우 많다. 일반적으로, sort 함수는 대부분 사용한다. 하지만, sort 함수이외에도 훌륭한 내장함수들이 많다. - std::binary_search - std::upper_bound - std::lower_bound - std:equal_range 위의 4가지 함수들은 매우 유용하게 사용될 것이다. 시간복잡도와 예제를 아래에서 설명하도록 하겠다. 1. std::binary_search 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 // binary_search example #include // std::cout #include // std::binary_search, std::s..
[BOJ 2875] 대회 or 인턴(반복문없는 if문 풀이, 시간복잡도 최소화) 이 문제는 그리디 알고리즘으로 분류되어 있다. 그리디는, 매순간 최선의 선택을 하는 알고리즘인데 이 문제에서 어떤 의도로 사용하라고 했는지는 잘 모르겠다. 문제를 풀기 위해서 다음의 과정을 거쳤다. 1. 최대 만들 수 있는 팀의 수를 구하기 2. 최대 만들 수 있는 팀 이외의 인원들을 K에 사용하기('-' 연산) 3. 2를 실시한 후에, K에 해당되는 인원이 아직도 남아있다면 팀을 해체시키기 위의 세 과정을 코드로 작성하였다. 구글링을 해보면 대부분 While문을 이용한 코드를 작성했다. While문을 이용한 코드는 N과 M이 크다면, 시간복잡도가 증가해서 효율성이 떨어지기 때문에, 아래의 코드가 더 효율적이라고 볼 수 있다. 해설코드(C++). 1 2 3 4 5 6 7 8 9 10 11 12 13 14..
[BOJ 1316] 그룹 단어 체커 이 문제에서 말하는 그룹 단어라고 함은 다음과 같다. "ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나고, kin도 k, i, n이 연속해서 나타나기 때문에 그룹 단어이지만, aabbbccb는 b가 떨어져서 나타나기 때문에 그룹 단어가 아니다." 위의 정의를 바탕으로 코드를 작성하면 된다. 만약에 문자열이 있다면, 문자열의 처음 문자부터 그룹 단어를 형성하고 있는지 확인하면 된다. 그룹 문자라면 연속적인 두 문자들이 계속 같을 것이고, 그룹 문자가 아니라면 연속적이지 않은 두 문자가 같은 문자를 가진 경우가 있을 것이다. 추가적으로, 이전의 문자를 통해서 이미 그룹 문자로 판명된 문자에 대해서는 검사할 필요가 없으므로, 별도의 bool 배열을 선언해준다. 해설코드(C++). 1 2 3 4 ..
[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..