Z
한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다.

N > 1인 경우, 배열을 크기가 2N-1 × 2N-1로 4등분 한 후에 재귀적으로 순서대로 방문한다.
다음 예는 22 × 22 크기의 배열을 방문한 순서이다.

N이 주어졌을 때, r행 c열을 몇 번째로 방문하는지 출력하는 프로그램을 작성하시오.
다음은 N=3일 때의 예이다.

입력
첫째 줄에 정수 N, r, c가 주어진다.
출력
r행 c열을 몇 번째로 방문했는지 출력한다.
사각형을 4개 단위로 쪼개면서 1칸이 남을 때까지 분할하여 해결하였습니다.
구현하는 과정에서 모든 칸에 대한 방문 순서를 기록했지만 메모리 초과와 시간 초과가 발생했고, 불필요한 칸을 쪼개기 때문에 이러한 문제가 발생했습니다.
해결
1) 인덱스를 비교해서 쪼갤 사각형 내에 있는지 확인하고, 그렇지 않다면 사각형의 크기 만큼 방문 순서를 더해줍니다.
2) 쪼갤 사각형 내에 있다면, 재귀를 호출합니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Z
*/
public class BOJ1074 {
static int pow[];
static int count = 0;
static int r, c;
static int answer = 0;
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String[] s = bufferedReader.readLine().split(" ");
int N = Integer.parseInt(s[0]);
r = Integer.parseInt(s[1]);
c = Integer.parseInt(s[2]);
pow = new int[N + 1];
pow[0] = 1;
for (int i = 1; i <= N; i++) {
pow[i] = 2 * pow[i - 1];
}
divide(0, 0, N);
System.out.println(answer);
}
static void divide(int x, int y, int n){
if (n == 0) {
if(x == r && y == c){
answer = count;
}
count++;
return;
}
int xx = x + pow[n - 1];
int yy = y + pow[n - 1];
int size = pow[n-1] * pow[n-1];
if (r < xx && c < yy) {
divide(x, y, n - 1);
}
else if(r < xx && c >= yy )
{
count += size;
divide(x, yy, n - 1);
} else if (r >= xx && c < yy) {
count += (2 * size);
divide(xx, y, n - 1);
} else {
count += (3 * size);
divide(x + pow[n - 1], y + pow[n - 1], n - 1);
}
}
}
'PS > 백준' 카테고리의 다른 글
[ BOJ 21318 ] 피아노 체조 ( JAVA ) (1) | 2024.06.20 |
---|---|
[ BOJ 20955 ] 민서의 응급 수술 ( java ) (1) | 2024.06.13 |
[ BOJ 7662 ] 이중 우선순위 큐 ( JAVA ) (1) | 2024.01.11 |
[ BOJ 2670 ] 연속부분최대곱 ( JAVA ) (0) | 2023.09.09 |
[ BOJ 26169 ] 세 번 이내에 사과를 먹자 ( JAVA ) (0) | 2023.09.07 |