알고리즘 문제(SOL)
[백준/1074/파이썬] Z
Mapin
2022. 4. 6. 18:37
https://www.acmicpc.net/problem/1074
Problem
- 한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다.
- N > 1인 경우, 배열을 크기가 2N-1 × 2N-1로 4등분 한 후에 재귀적으로 순서대로 방문한다.
조건
- 첫째 줄에 정수 N, r, c가 주어진다.
SOL
분할정복의 개념이 쓰이기는 하지만, 결국은 규칙을 찾아내는 문제였다.
"분할정복"이라고 했을 때, 직관적으로 "분할해서, 문제를 해결해야한다" 개념이 아주 짙은 문제였다.
이때, 재귀적으로 구현을 할 수도 있고, 규칙성을 나타낼 수 있다면, 반복문을 써도된다.
이 문제는 2^N *2^N 크기의 배열을 4등분하고, 또 4등분하고 ... 이런식으로 해서, Z자 모양으로 순차적을 방문했을 때, R,C가 몇번째로 방문되는지 알아내는 문제이다.
우선 4등분을 한다니까, 4가지 구역으로 나눌 수 있을 거고, 각 구역의 시작점을 보면, 규칙성이 발견이 된다.
좌표평면처럼 , 4등분된 구역을 1사분면 ~ 4사분면으로 부르도록 하겠다.
1사분면의 시작점은 0 = 4*4*0
2사분면의 시작점은 16 = 4*4 * 1
3사분면의 시작점은 32 = 4*4* 2
4사분면의 시작점은 48 = 4*4* 3
즉, 4등분한 크기의 제곱의 0~3곱으로 표현할 수 있다.
Psudo code로 간단히 작성하면 아래와 같이 될거다.
## Psudo code
if 1사분면:
ans+=(크기)^2 *0
if 2사분면:
ans+=(크기)^2 *1
if 3사분면:
ans+=(크기)^2 *2
if 4사분면:
ans+=(크기)^2 *3
이때, 우리가 찾고싶은 좌표 (R,C)도 해당 좌표에 맞게 설정을 해줘야 하게 된다.
예를들어, R= 0, C=5 인 17이라면, 큰 사각형에서 봤을 때는 17번째지만, 2사분면을 다시 4등분해서 쪼개면,
1사분면에 있게되고, 시작점(16)을 0이라고 했을때, 17은 1이 된다.
즉, C의 좌표도 압축을 해줘야한다.
## Psudo code
if 1사분면:
#압축 필요없음
ans+=(크기)^2 *0
if 2사분면:
x좌표 압축
ans+=(크기)^2 *1
if 3사분면:
y좌표 압축
ans+=(크기)^2 *2
if 4사분면:
y,x좌표 압축
ans+=(크기)^2 *3
위의 Psudo Code를 코드로 나태내면 아래와 같다!
# "Z"
N,R,C =map(int,input().split())
cnt=0
while N !=0:
N -=1
if 0<=R<2**N and 0<=C<2**N:
cnt+=(2**N) * (2**N) *0
if 0<=R<2**N and 2**N<=C<2**(N+1):
cnt+=(2**N) *(2**N) *1
C-=2**N
if 2**N<=R<2**(N+1) and 0<=C<2**N:
cnt+=(2**N) * (2**N) *2
R-=2**N
if 2**N<=R<2**(N+1) and 2**N<=C<2**(N+1):
cnt += (2**N) *(2**N) *3
C-=2**N
R-=2**N
print(cnt)