본문 바로가기

BOJ737

백준 2133 자바 - 타일 채우기 (BOJ 2133 JAVA) 문제 : boj2133 1. 우선, 2x1과 1x2짜리 타일을 사용해야 하므로 무슨짓을 하던 n이 홀수라면 전체 칸 수(3 x n)가 홀수이므로 2칸짜리 타일로 타일링이 불가능하다. 즉, n이 짝수일 때만 타일링이 가능하다. 이 부분은 예외로 처리해준다. 2. 가장 기본적인 규칙성을 찾아보자. n=2일 때 3가지 모양이 나온다. 3. 그럼 n=4일 때는 n=2일 때 나왔던 모양에서 각각의 경우 3가지 모양이 더 추가되므로 'n=2일때의 모양 x 3'이 됨을 쉽게 알 수 있다. 예를 들어 위 n=2일때 중 첫번째 그림에 대해서만 그려보면 다음과 같다. 일단 여기까지, f(n)을 3 x n 타일링에서 n개의 가로칸으로 가능한 타일링의 경우의 수라 하자. 그럼 f(4) = f(2) * 3 임을 알 수 있다. .. 2021. 12. 30.
백준 2193 자바 - 이친수 (BOJ 2193 JAVA) 문제 : boj2193 1. N=1 일 때를 생각해보자. 0으로 시작하면 안되므로, 0으로 끝나는 수는 0개이고 1로 끝나는 수는 1개이다. (0과 1) 2. N=2 일 때를 생각해보자. 0으로 끝나려면 어떻게 해야 할까? 이 문제의 경우 1이 두번 연속으로 나오지 않기만 하면 된다. 따라서 이전 값이 0으로 끝나거나, 1으로 끝나거나 상관 없이 0을 붙일 수 있다. 반면에 끝이 1로 끝나려면 이전에 0으로 끝난 경우에 대해서만 1을 추가로 붙일 수 있다. 3. 이제 위의 규칙을 계산하기 위해 dp를 사용해보자. dp[n][x(=2)]를 n자리수에서 x로 끝나는 경우의 수라 정의하자. 이 때 n=5인 경우에 대해 그려보면 다음과 같다. 점화식으로 나타내면 dp[n][0] = dp[n-1][0] + dp[.. 2021. 12. 30.
백준 2294 자바 - 동전 2 (BOJ 2294 JAVA) 문제 : boj2294 1. 우선 문제에서 필요없는 정보를 제한해보자. 1.1 '사용한 동전의 구성이 같은데, 순서만 다른 것은 같은 경우이다.' -> 이 조건은 해당 가치를 표현하는 경우의 수를 구할때나 의미가 있다. '사용한 동전의 최소 개수'를 구하는 문제이므로 무시해도 된다. 1.2 '가치가 같은 동전이 여러 번 주어질 수도 있다.' -> 가치가 동일한 동전의 경우 연산을 느리게 할 뿐이므로, 동일한 동전이 주어진 경우는 HashSet 등을 사용해 제거하면 될 것임을 생각할 수 있다. 1.3 'k 2021. 12. 30.
백준 2293 자바 - 동전 1 (BOJ 2293 JAVA) 문제 : boj2293 1. 우선 문제를 좀 더 간단히 변경해서 봐보자. 1,2,5의 가치를 가지는 동전이 있고, 그 가치의 합이 10이 되게 하려 한다. 그리고 문제와 다르게 동전의 구성이 같아도 순서가 다르면 다른 경우로 치고 생각해보자. 그럼 1차원 배열을 활용한 dp로 아래와 같이 풀 수 있다. (냅색 문제처럼 풀면 된다.) 1.1 우선 초기값이다. dp[idx]는 1,2,5의 동전들을 가지고 idx의 가치를 가지는 경우의 수를 나타낸다. dp[0]은 실제론 불가하지만, 초기값으로 넣어준다. 그래야 동전 하나를 가지고 표현할 수 있는 경우에 대해서도 별도로 처리하지 않고 점화식 하나로 계산하기 편하다. (예를들어 2의 가치를 표현하려면 동전2짜리 하나만 쓸 수 있다. 식으로는 dp[2-2]이다. .. 2021. 12. 29.
백준 2757 자바 - 액셀 (BOJ 2757 JAVA) 문제 : boj2757 R값은 그냥 그대로 출력하면 된다. C값의 경우, 10진수를 26진수로 변경한다고 생각하면 좀 편하게 생각할 수 있다. C값은 뒤부터 한 자리씩 26으로 나눠보면서 맞는 문자를 매칭시키는 방식으로 찾을 수 있다. 코드 : github import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Main { private void solution() throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringBuilder answ.. 2021. 12. 28.
백준 2012 자바 - 등수 매기기 (BOJ 2012 JAVA) 문제 : boj2012 1. 흔히 생각해볼만한게, 예를들어 '1 8 4 5 6'과 같은 입력이 있는 경우 총 1~5등 까지를 매칭시켜야 한다. 그렇다면 1~5등 사이 중 일단 자기가 원한 등수가 가능한 녀석들을 매칭시키자. 그럼 1, 4, 5는 1~5등 내에 매칭이 가능할 것이다. 이제 8과 6이 남는데, 당연하게도 정렬해서 매칭시키는 것이 더 정답에 가까울 것임을 유추할 수 있다. 따라서 정렬 후 차례대로 남는 위치에 매칭시키면 답을 구할 수 있다. '1'의 방법을 정리하면 1.1 N을 입력받는다. 1.2 1~N에 바로 매칭이 가능한 예상등수를 매칭시킨다. 1.3 남는 등수를 정렬한 후, 1~N 사이 남는 등수에 매칭시킨다. 이 된다. 2. 그런데 사실 더 쉬운 방법이 있다. 어차피 (|A-B|)의 합.. 2021. 12. 27.
백준 20127 자바 - Y-수열 (BOJ 20127 JAVA) 문제 : boj20127 증가수열 또는 감소수열인 것은 해결 로직을 세우는데에 상관이 없다. 증가수열, 감소수열 둘다 별도 로직으로 계산한다고 생각하면 그 중 작은걸 출력하면 된다. 기본적으론 이런데, 이 문제의 경우 정답률이 낮은만큼 많은 경우를 세세하게 예외처리해줘야 통과할 수 있다. 이하 여러가지 케이스에 대해 설명해본다. 1. 기본 로직은 증가수열을 체크한다면 수가 작아지는 부분을, 감소수열을 체크한다면 수가 커지는 부분의 개수가 2개 이상이라면 증가 혹은 감소수열이 될 수 없다. 예를들어 '예제 입력 1'에 대해 증가수열로써 체크한다면 감소하는 경우가 1번 이하이므로 가능하다! 하지만 감소수열로써 체크한다면 감소하는 경우가 2번 이상이므로 감소수열로는 만들 수 없다. 2. 이번엔 '1'와 같은 .. 2021. 12. 26.
백준 10997 자바 - 별 찍기 - 22 (BOJ 10997 JAVA) 문제 : boj10997 1. 일단 규칙부터 유추해보자. 대강 n이 주어질 때 우측상단부터 시작해서 n-0.5 바퀴 돌리는 별찍기라 볼 수 있다. 예를들어 3이라면 2.5바퀴를 돌린 형태이다. 2. 좀 더 구체적으로 짤 수 있는 로직을 생각해 보자면, 1일 때는 그냥 예외로써 '*' 하나만 출력해주면 되겠고, n이 2 이상이라면 row의 개수는 3+4*n, column의 개수는 1+4*n 이 된다. 그리고 우측 상단부터 시작해서 좌,하,우,상의 방향을 순서대로 돌리면서 갈 수 있는 곳까지 별을 찍으면 된다. 갈 수 있는 조건은 배열의 끝 혹은 가려는 방향으로 2칸 앞이 이미 별인 경우 해당 위치까지만 찍을 수 있다. 즉 row와 column 개수에 대한 점화식만 잘 세우고, 그 이후로는 단순 구현으로 풀.. 2021. 12. 25.
백준 4485 자바 - 녹색 옷 입은 애가 젤다지? (BOJ 4485 JAVA) 문제 : boj4485 1. 젤다가 활강하는 장면! 야숨2가 나오면 알고리즘을 당분간 못(안)풀 수 있으니 알고리즘을 미리 풀고 키핑해둬야겠다ㅋㅋㅋ 2. 만약 이런식의 문제에서 이동 가능한게 좌측과 아래쪽 뿐이었다면 DP로도 풀 수 있다. 하지만 이 문제와 같이 4방향으로 이동이 가능하다면, DP로 풀어보려면 결국 모든 경우를 다 봐야해서 시간초과가 나게 될 것이다. O((N^2)^2) 한가지 떠올릴만한 점은 결국 배열도 그래프라는 것이다. 예제 입력의 아래와 같은 부분을 그래프 형태로 그려보면 다음과 같다. 3 5 5 4 3 9 1 3 2 7 결국 이 문제는 가장 적게 잃으면서 진행해야 하므로, 그냥 그래프에서 start부터 goal 까지의 최단거리를 찾는 것과 동일하다! 그리고 가중치가 모두 양수이면.. 2021. 12. 24.
백준 2670 자바 - 연속부분최대곱 (BOJ 2670 JAVA) 문제 : boj2670 1. 모든 경우를 보면서, 이전 값이 1.0 보다 크다면 현재 입력받은 수를 곱해준다. 이전까지 구해둔 값이 1.0 이하라면 현재값을 곱하는 것이 손해이므로, 현재값부터 다시 연속된 수를 파악하면 된다. 예를들어 1.2 0.9 1.5 가 있고 현재 1.5를 살펴볼 차례라고 해보자. 이전까지의 값의 곱인 1.2*0.9는 1.08이므로 1.0보다 크다. 따라서 1.5까지 곱해서 1.620이 답이 된다. 반면에 1.1 0.9 1.5라면 1.1*0.9 = 0.99 이므로 1.5에 곱하면 오히려 손해이다. 따라서 1.5부터 다시 구해나가는 것이 더 이득이다. 정리하면 현재 입력받은 수가 cur, 이전까지 계산하던 값이 bf 라고 해보자. bf>1.0이라면 bf = bf * cur이 될 것이.. 2021. 12. 23.