[백준/Java] 1074 - Z

2025. 9. 14. 15:35·코딩테스트/백준

https://www.acmicpc.net/problem/1074

문제


풀이

N이 15까지 커질 수 있기 때문에 2^15 배열을 만드는 것은 시간초과가 발생할 수 있다

분할정복을 활용하는 문제이다

 

전체 사각형을 4개 사분면으로 나누어 `(r, c)`가 어느 사분면에 있는지 알아내는 것이 중요하다

N이 2라고 가정하면 (4 x 4 사각형) 아래 배열이 나올 것이다

사각형을 절반으로 나누어 사분면을 만든다고 하면 아래 그림처럼 될 것이다 (2 x 2 사각형 4개)

`half = 2`

주어진 `(r, c)` 가 어느 사분면에 속하는지 구해야 한다

1사분면: `r < half` 이고 `c < half`

2사분면: `r < half` 이고 `c >= half`

3사분면: `r >= half` 이고 `c < half`

4사분면: `r >= half` 이고 `c >= half`

 

만약 `(r, c)`가 1사분면에 있다면 이전 사분면을 하나도 건너뛰지 않았다

2사분면에 있다면 1사분면을 방문하고 온 것이다

따라서 결과값에 `half * half`(1사분면의 크기)를 더해줘야 한다

3, 4사분면도 똑같이 건너뛴 사분면을 더해주어야 한다

3사분면 -> `2 * (half * half)`

4사분면 -> `3 * (half * half)`

 

`(r, c)`가 어느 사분면인지 알았다면 또 그 사분면에서 몇 번째인지 다시 찾아야 한다

그래서 좌표를 그 사분면의 시작점 기준으로 바꿔줘야 한다

만약 2사분면이라면 재귀 호출에 `(r, c - half)`를 넘겨줘야 한다

 

이렇게 N이 0이 될 때까지 재귀호출을 하면서 누적된 값이 정답이다

코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

	static int count; // 방문 카운트

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		StringBuilder sb = new StringBuilder();

		st = new StringTokenizer(br.readLine());
		int N = Integer.parseInt(st.nextToken());
		int r = Integer.parseInt(st.nextToken());
		int c = Integer.parseInt(st.nextToken());

		find(N, r, c);
		System.out.println(count);

		br.close();
	}

	// 분할 정복
	static void find(int N, int r, int c) {
		// N이 0이 되면 종료 (사각형이 더이상 안만들어짐)
		if (N == 0) {
			return;
		}

		// 주어진 N의 반을 구한다
		int half = (int) Math.pow(2, N - 1);
		int square = half * half; // 반으로 나눈 사각형의 넓이

		// 1사분면(왼쪽 위)
		if (r < half && c < half) {
			find(N - 1, r, c);
		}
		// 2사분면(오른쪽 위)
		else if (r < half && c >= half) {
			count += square; // 1시분면 크기만큼 더함
			find(N - 1, r, c - half); // 좌표 재조정
		}
		// 3사분면(왼쪽 아래)
		else if (r >= half && c < half) {
			count += 2 * square; // 1, 2사분면 크기만큼 더함
			find(N - 1, r - half, c); // 좌표 재조정
		}
		// 4사분면(오른쪽 아래)
		else {
			count += 3 * square; // 1, 2, 3사분면 크기만큼 더함
			find(N - 1, r - half, c - half); // 좌표 재조정
		}
	}
}

결과

'코딩테스트/백준' 카테고리의 다른 글
  • [백준/Java] 7569 - 토마토
  • [백준/Java] 5430 - AC
  • [백준/Java] 14940 - 쉬운 최단거리
  • [백준/Java] 11403 - 경로 찾기
KDH.dev
KDH.dev
  • KDH.dev
    CodingHard
    KDH.dev
  • 전체
    오늘
    어제
    • 전체글 (81)
      • 코딩테스트 (74)
        • 프로그래머스 (13)
        • 백준 (61)
      • CS (3)
        • 네트워크 (3)
      • Spring (1)
      • Java (3)
        • 자료구조 (3)
        • 알고리즘 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    CS
    16935
    프로그래머스 Lv.0
    18111
    부트캠프후기
    14940
    코딩테스트
    자바
    네트워크
    17626
    백준
    30804
    5525
    11660
    자료구조
    [LG유플러스] 유레카 백엔드 개발자
    21736
    멀티캠퍼스it부트캠프
    프로그래머스
    13913
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
KDH.dev
[백준/Java] 1074 - Z
상단으로

티스토리툴바