-
2448번 - 별 찍기 - 11알고리즘/백준 2023. 8. 3. 17:40
1️⃣ 재귀
✏️ 풀이 과정
프랙탈 도형을 만드는 문제입니다. 풀이를 위해서는 두 가지 요소가 필요한데 하나는 정확히 어떤 도형이 반복되는지 기준을 잡아야 한다는 것이고 다른 하나는 어떤 방식으로 다음 단계의 도형이 만들어지는 지 규칙을 알아야 합니다.
결론적으로 말하자면 반복되는 도형은 삼각형 모양의 최초의 별 6개로 시작하는 도형이고 다음 단계 도형의 규칙은 현재 단계 도형 2개를 아래에 붙여 새로운 삼각형을 만드는 것입니다.
재귀로 이를 구현할 때 가장 문제가 되는 부분은 도대체 삼각형 중간의 빈 공간을 어떻게 계산해서 메워야하는지 일텐데요, 삼각형을 그대로 삼각형이라고 생각하기보다는 공백까지 포함해서 직사각형을 반복한다고 생각하는 쪽이 편리합니다.
위 방법대로 로직을 구현하면 우선 1단계 삼각형을 String ArrayList에 저장하고(나중에 String.join메서드를 이용해 한 번에 이어붙입니다.) 다음 단계를 계산할 때 1단계 삼각형을 아래 한 칸 공백을 두고 두 번 붙여넣고, 1단계 삼각형 양쪽에 공백(1단계의 사이즈와 같습니다.)을 더해서 새로 변경된 직사각형을 얻을 수 있습니다.
이를 통해서 각 단계의 도형을 얻을 수 있는데 남은 것은 주어지는 숫자와 단계의 연관성을 찾는 것입니다. N의 식은 문제에서 주어지기 때문에 이를 고려해서 계산해보면 N이 주어졌을 때 거쳐야 하는 단계 수는 log_2(N/3)과 같습니다. Java에서 log_2 메서드가 주어지지 않기 때문에 밑변환 공식을 이용해서 log_2(N/3)의 값을 계산했습니다.
⏱ 시간 복잡도
각 단계마다 사이즈가 2배로 들어나기 때문에 전체 연산 횟수는 3 + 6 + 12 + ... + 3 x 2^N과 같고 등비급수의 합과 같기 때문에 시간 복잡도는 O(2^N)이 됩니다.
💻 코드
Java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; public class Main{ static int N; static ArrayList<String> strs; static void make(int n) { if(n == N) { return; } int size = strs.size(); StringBuilder sb = new StringBuilder(); String cur; for(int i=0;i<size;i++) { sb.append(" "); } for(int i=0;i<size;i++) { cur = strs.get(i); strs.add(cur+" "+cur); strs.set(i, sb+cur+sb); } make(n+1); } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); N = (int) (Math.log10(Integer.parseInt(br.readLine()) / 3) / Math.log10(2)); strs = new ArrayList<>(); strs.add(" * "); strs.add(" * * "); strs.add("*****"); make(0); System.out.print(String.join("\n", strs)); br.close(); } }
'알고리즘 > 백준' 카테고리의 다른 글
11053번, 12015번 - 가장 긴 증가하는 부분 수열 (0) 2023.08.03 2638번 - 치즈 (0) 2023.08.03 9663번 - N-Queen (0) 2023.08.03 2580번 - 스도쿠 (0) 2023.08.01 16637번 - 괄호 추가하기 (0) 2023.08.01