ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 1074 Z
    ALGORITHM/BOJ 2021. 7. 13. 23:00

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

     

    1074번: Z

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

    www.acmicpc.net

    2021-07-13


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
     
    public class Main1074 {
        public static int N, r, c;
        public static void main(String[] args) throws IOException {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st = new StringTokenizer(bf.readLine());
            N = Integer.parseInt(st.nextToken());
            r = Integer.parseInt(st.nextToken());
            c = Integer.parseInt(st.nextToken());
            int answer = 0;
     
            int x = (1 << N) >> 1// init
            int y = x;
     
            while(N-- > 0) {
                int quarter =  (1 << N) * (1 << N);
                int move = (1 << N) >> 1;
                if (r < x && c < y) { // 1
                    x -= move;
                    y -= move;
                } else if (r < x && c >= y) { // 2
                    x -= move;
                    y += move;
                    answer += quarter;
                } else if (r >= x && c < y) { // 3
                    x += move;
                    y -= move;
                    answer += quarter*2;
                } else {
                    x += move;
                    y += move;
                    answer += quarter*3;
                }
            }
     
            System.out.println(answer);
        }
    }
    cs

     

    #문제풀이

    분할정복 문제이다,,  개인적으로 이게 실버1? 인지 잘 모르겠는 문제이다..

    1,2,3,4 분면을 나눠서 범위를 좁혀 나가는게 포인트인 문제이다. 

     

    두 번째 예제 N == 3, r == 7, c == 7 을 기준으로 본다.

    처음 초기값(x, y)은 정중앙인 2^N / 2 ((1<< N) >> 1) 으로 잡았다. 

    그리고 4개의 사분면은 아래와 같은 방법으로 나눌 수 있다.

    그리고 원하는 지점(7, 7)을 찾을 때까지, 해당 사분면에서 또 다시 4등분으로 나누면 된다.

    또한, 여기서 각 사분면의 중심점이 새로 바뀐 것을 아래와 같이 확인할 수 있다.

    이 때, 기준은 초기값과 같이  2^N / 2 ((1<< N) >> 1) (->move)이다.

     

    1사분면  : (x -= 2, y-=2)

    2사분면 : (x-=2, y+=2)

    3사분면 : (x+=2, y-=2)

    4사분면 : (x+=2, y+=2)

    또한, 각 사분면이 움직일 때마다 더해야하는 수가 있다.

    예를 들어, 내가 찾아야하는 (r, c)가 3사분면 쪽에 있다면, 1+2 사분면에서 계산해야하는 값들을 더한 후 이동해야 된다. 왜냐하면 우리가 어차피 3사분면에 이동하기 전까지 1+2사분면에서 카운팅 되는 숫자는 정해져있기 때문이다. 그래서 1사분면은 이동해야할 숫자를 더할 필요가 없다.

    그리고 이것이 2^N (1<< N)*(1 << N)  (->quarter)인 것을 알 수 있다.

     

    1사분면 : x

    2사분면 : (1<<N)*(1<<N)

    3사분면 : (1<<N)*(1<<N) * 2

    4사분면 : (1<<N)*(1<<N) * 3

     

    이것들을 N이 0이 될 때까지 반복하면 된다.

    'ALGORITHM > BOJ' 카테고리의 다른 글

    [백준] 10159 저울  (0) 2021.08.31
    [백준] 1717 집합의 표현  (0) 2021.08.14
    [백준] 2630 색종이 만들기  (0) 2021.07.09
    [백준] 13913 숨바꼭질 4  (0) 2021.07.09
    [백준] 12851 숨바꼭질 2  (0) 2021.06.27

    댓글

Programming Diary