문제 풀이

[백준] 1074번 Z

컴영 2020. 6. 23. 16:35

1074 Z


문제


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

만약, 2차원 배열의 크기가 2^N * 2^N라서 왼쪽 위에 있는 칸이 하나가 아니라면, 배열을 4등분 한 후에 (크기가 같은 2^(N-1)로) 재귀적으로 순서대로 방문한다.


다음 예는 2^2 * 2^2 크기의 배열을 방문한 순서이다.


N이 주어졌을 때, (r, c)를 몇 번째로 방문하는지 출력하는 프로그램을 작성하시오.


입력


첫째 줄에 N r c가 주어진다. N은 15보다 작거나 같은 자연수이고, r과 c는 0보다 크거나 같고, 2^N-1보다 작거나 같은 정수이다


출력


첫째 줄에 문제의 정답을 출력한다.



풀이)

분할정복 문제이다.


(r,c) 좌표에 해당하는 칸이 나올 때까지 4등분 한 뒤,


   mid    2^n

 1

 3


4사분면 중 어느 사분면에 속하는 지 알아내어 현재 사분면보다 이전에 방문한 사분면의 칸 수를 더해주면 된다.


코드)


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
#include <stdio.h>
#include <cmath>
using namespace std;
 
int main(){
    int n,r,c,result =0;
    scanf("%d %d %d",&n,&r,&c);
    
    int mid = 0//4등분의 중간 좌표 값
 
    while(n>0){
        int place;//사분면 값
        mid = pow(2,n) / 2;
        
        //좌표가 어느 사분면에 속하는지
        if(r<&& c<s) place = 0//1사분면
        else if(r>=&& c<s) place = 1//2사분면
        else if(r<&& c>=s) place = 2//3사분면
        else{//4사분면
            place = 3;
        }
 
        result += pow(mid,2* place;// 이전 사분면들의 칸 수를 더해줌,
//각 사분면에 속한 칸 * 현재사분면 - 1
        r %= mid;
        c %= mid; // 좌표를 작은 사각형의 좌표로 변경
        
        n--;
    }
    
    printf("%d\n",result);
    
    return 0;
}

cs