https://www.acmicpc.net/problem/1074
1074번: Z
한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다. N > 1인 경우, 배열을
www.acmicpc.net
문제
한수는 크기가 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열을 몇 번째로 방문했는지 출력한다.
소스코드
import java.io.*;
import java.util.StringTokenizer;
class Main {
static int result = 0;
static int r;
static int c;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int N = Integer.parseInt(st.nextToken());
r = Integer.parseInt(st.nextToken()); //행
c = Integer.parseInt(st.nextToken()); //열
int size = (int) Math.pow(2, N); //2^N
partition(0, 0, size);
System.out.println(result - 1);
}
private static void partition(int startX, int startY, int size) {
//1x1 or 2x2 격자일 경우
if(size <= 2){
findXY(startX, startY);
return;
}
int half = size/2;
//찾으려는 r행 c열이 왼쪽 상단 or 오른쪽 상단 or 왼쪽 하단 or 오른쪽 하단 중 어느 위치인지 판단
boolean left = startX <= c && c < startX + half;
boolean right = startX + half <= c && c < startX + size;
boolean top = startY <= r && r < startY + half;
boolean bottom = startY + half <= r && r < startY + size;
if(left && top){ //왼쪽 하단
partition(startX, startY, half);
}else if(right && top){ //오른쪽 상단
result = result + ((half * half) * 1);
partition(startX+half, startY, half);
}else if(left && bottom){ //왼쪽 하단
result = result + ((half * half) * 2);
partition(startX, startY+half, half);
}else if(right && bottom){ //오른쪽 상단
result = result + ((half * half) * 3);
partition(startX+half, startY+half, half);
}
}
//분할된 1x1 or 2x2 격자에서 원하는 r행 c열의 값 찾기
private static boolean findXY(int startX, int startY){
//Z 방향으로 확인
for (int j = startY; j < startY + 2; j++) {
for (int i = startX; i < startX+2; i++) {
result++;
if (j == r && i == c) {
return true;
}
}
}
return false;
}
}
해결 방법
- 탐색 범위를 좁히기 위해 분할정복을 한다.
- 쪼개진 범위의 첫 번째 값을 알기위해 분할정복 과정에서 count 값 사용한다.
- 탐색 범위가 1x1 or 2x2 만큼 좁혀졌다면 원하는 행, 열의 값을 찾는다.
https://lotuus.tistory.com/105
[백준] 1074번 Z 자바 (분할정복)
목차 https://www.acmicpc.net/problem/1074 1074번: Z 한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로
lotuus.tistory.com
'알고리즘 > 백준' 카테고리의 다른 글
2636번 : 치즈 (1) | 2023.10.26 |
---|---|
2559번 : 수열 (0) | 2023.10.18 |
20056번 : 마법사 상어와 파이어볼 (1) | 2023.10.17 |
14725번 : 개미굴 (1) | 2023.10.17 |
14716번 : 현수막 (1) | 2023.10.09 |