728x90
300x250
https://www.acmicpc.net/problem/1074
분할정복은 패턴을 파악하여 하나의 큰 문제를 작은 부분 문제로 쪼개서 각각 계산하고 이들을 합하여 답을 구한다.
N=3이면, 2^N* 2^N 배열이 생긴다.
노란색 음영인 (5,4)의 방문순서를 구한다고 할때,
재귀는 2^(N-1)* 2^(N-1)로 4등분하므로 2^2 * 2^2 => 4*4가 된다.
4*4 크기만큼 4등분 해서 보면 (5,4)의 위치는 1,2,3,4번째중 4번째로 속하게 된다.
그러면 나머지 1,2,3은 모두 다 방문해야하므로 4*4*3 을 통해서 한번에 방문 횟수를 구하고
나머지 4번째 화면에 대한 재귀를 수행한다.
N-1하여 아까와 마찬가지로 1,2,3,4 번째 확인하여 재귀 수행..
이번에는 1번째에 존재하기에 별도 덧셈없이 다시 쪼갠다.
<Java 코드>
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int N;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//System.setIn(new FileInputStream("Test.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
int row = Integer.parseInt(st.nextToken());
int col = Integer.parseInt(st.nextToken());
System.out.println(fun(N, row, col));
}
public static int fun(int n, int r, int c) {
int sum = 0;
if (n > 0) {
int mid = (int) Math.pow(2, n) / 2;
if (r < mid && c < mid) {
sum += fun(n - 1, r, c);
} else if (r < mid && c >= mid) {
sum += (mid * mid) + fun(n - 1, r, c - mid);
} else if (r >= mid && c < mid) {
sum += (mid * mid * 2) + fun(n - 1, r - mid, c);
} else {
sum += (mid * mid * 3) + fun(n - 1, r - mid, c - mid);
}
}
return sum;
}
}
728x90
'알고리즘 > 분할정복' 카테고리의 다른 글
백준 1517번: 버블 소트 [분할정복][재귀] - Java (0) | 2020.09.10 |
---|---|
백준 2448번: 별 찍기 - 11 [분할정복][재귀] - Java (0) | 2020.09.08 |
백준 2447번: 별 찍기 - 10 [분할정복][재귀] - Java (0) | 2020.09.06 |
백준 1992번: 쿼드트리 [분할정복][재귀] - Java (0) | 2020.09.06 |
백준 11729번: 하노이 탑 이동 순서 [분할정복][재귀] - Java (0) | 2020.09.06 |