(C++) [백준 1074번] Z
https://www.acmicpc.net/problem/1074
1074번: Z
한수는 크기가 2N × 2N인 2차원 배열을 Z모양으로 탐색하려고 한다. 예를 들어, 2×2배열을 왼쪽 위칸, 오른쪽 위칸, 왼쪽 아래칸, 오른쪽 아래칸 순서대로 방문하면 Z모양이다. N > 1인 경우, 배열을
www.acmicpc.net
예전에 재귀에 대해서 거의 모를 때 무작정 풀었다가 정말 고생했었던 기억이 난다.
2N*2N을 Z모양으로 탐색한다는 건 왼쪽 위,오른쪽 위,왼쪽 아래,오른쪽 아래순으로 간다는거다. 예를 들어 문제 예시의 2*2 사각형을 보면 0,1,2,3 순이다.
그리고 잘 보면 r행 c열을 구할때 직접 따라가보지 않더라도 구할 수가 있다. 예를 들어 n=2,r=3,c=1이라면
순서대로 따라가도 11이겠지만 n=1인 사각형 4개로 나눴을때 왼쪽 아래(3번째) 사각형에 해당한다. 이는 1번째,2번째 사각형을 지나쳐온게 되므로 n=1인 사각형 2개를 지나친거고, 3번째 사각형의 오른쪽 아래 칸이므로 이 값은 3이다. 즉 4*2+3=11로도 구할수가 있다.
이 문제를 재귀로 풀기 위해서는 먼저 함수를 정의해야 하는데, 함수는 다음과 같다.
int func(int n,int r,int c): z모양으로 재귀적으로 방문했을 때 r행 c열을 방문한 값
그리고 half라는 값이 있는데, 이 값은 2^n-1을 나타낸다. 아까 n=2일때 n=1인 사각형들을 지나쳤는데 그 사각형들을 구하기 위한 값이다.
또 기저 조건(base condition)은 n=0일때 return 0이다. n=1으로도 풀 수 있지만 코드가 복잡해지므로 n=0이 나은 것 같다.
마지막으로 4가지 조건에 따라 재귀하게 되는데, 리턴 값은 다음과 같다.
1번째 사각형일 때: return func(n-1,r,c)
2번째 사각형일 때: return half*half+func(n-1,r,c-half)
3번째 사각형일 때: return 2*half*half+func(n-1,r-half,c)
4번째 사각형일 때: return 3*half*half+func(n-1,r-half,c-half)
조건은 다음과 같다.
1번째 사각형일 때: if(r<half && c<half)
2번째 사각형일 때: if(r<half && c>=half)
3번째 사각형일 때: if(r>=half && c<half)
4번째 사각형일 때: else or if(r>=half && c>=half)
half는 다음 4등분할 사각형의 크기인데, r이 half보다 작으면 위쪽, c가 half보다 작으면 왼쪽이라고 생각하면 된다.
코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include <iostream>
using namespace std;
int Z(int n, int r, int c)
{
if (n == 0)return 0;
int half = 1 << (n - 1);
if (r < half && c < half)
return Z(n - 1, r, c);
else if (r < half && c >= half)
return half * half + Z(n - 1, r, c - half);
else if (r >= half && c < half)
return 2 * half * half + Z(n - 1, r - half, c);
else
return 3 * half * half + Z(n - 1, r - half, c - half);
}
int main()
{
cin.tie(0); ios::sync_with_stdio(0);
int n, r, c;
cin >> n >> r >> c;
cout << Z(n, r, c);
}
|
cs |

