코딍코딍
코딩기록
코딍코딍
전체 방문자
오늘
어제
  • 분류 전체보기 (271)
    • 개발 (2)
    • Java (1)
    • 스프링 (28)
    • JPA (11)
    • Git (3)
    • 알고리즘 (160)
      • 백준 (132)
      • 프로그래머스 (8)
      • SWEA (20)
    • 토이 프로젝트 (14)
      • 간단한 Springboot CRUD (1)
      • 게시판 프로젝트 (13)
    • 알고리즘 개념정리 (8)
    • 오류 해결 (13)
    • 보류 (0)
    • AWS (5)
    • 트러블 슈팅 (0)
    • 회고 (3)
    • CS (4)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

최근 글

티스토리

hELLO · Designed By 정상우.
코딍코딍

코딩기록

알고리즘/백준

1074번 : Z

2023. 10. 17. 14:41

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;
    }
}

 

해결 방법

  1. 탐색 범위를 좁히기 위해 분할정복을 한다.
  2. 쪼개진 범위의 첫 번째 값을 알기위해 분할정복 과정에서 count 값 사용한다.
  3. 탐색 범위가 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
    '알고리즘/백준' 카테고리의 다른 글
    • 2636번 : 치즈
    • 2559번 : 수열
    • 20056번 : 마법사 상어와 파이어볼
    • 14725번 : 개미굴
    코딍코딍
    코딍코딍
    ㅎ2

    티스토리툴바