코딩공작소
[백준]Z(분할정복)다시풀어보자 본문
https://www.acmicpc.net/problem/1074
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,
www.acmicpc.net
어떤 천재의 풀이를 이해만 했다... 재귀를 써야하나 여러가지 방법을 생각했지만 2^15까지의 배열의 크기가 나오는
문제이다. 분할정복이란 가장 최소의 단위까지 분할을 하고 문제를 처리해주는 것이다.
분할은 쪼개주면서 하는 것이고 이제 그것들을 어떻게 활용해서 답을 구할지를 구현해야한다..(정복!!)
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 <iostream>
#include <cmath>
using namespace std;
int N, r, c;
int cnt = 0;;
void solve(int y, int x, int jump) {
if (y == r && x == c) { //최소의 분할에서 구하고하는 값과 일치.
printf("%d\n", cnt);
return;
}
//구하고자하는 점이 속한 영역을 계속 분할
//else의 경우에서 값을 업데이트 하기때문에 순서가 중요함 Z순서로 함수순서구성.**
if ((x <= c && c < x + jump) && (y <= r && r < y + jump)) {
solve(y, x, jump / 2);
solve(y, x + jump / 2, jump / 2);
solve(y + jump / 2, x, jump / 2);
solve(y + jump / 2, x + jump / 2, jump / 2);
}//구하고자하는 점이 속하지 않는 곳은 빠르게 값만 업데이트하고 리턴.
else {
cnt += jump * jump;
return;
}
}
int main()
{
cin >> N >> r >> c;
N = pow(2, N);
solve(0,0,N);
return 0;
}
|
cs |
'알고리즘 > 그리디&완탐' 카테고리의 다른 글
[백트래킹]끝점을 늘려가면서 탐색하는 순열조합+a (0) | 2019.08.11 |
---|---|
[백트래킹]조합,순열,중복조합,중복순열 (0) | 2019.08.11 |
[백준]체스판다시칠하기 (0) | 2019.08.06 |
[백준]색종이 붙이기 (1) | 2019.08.06 |
[백준]스타트링크(두번째) (0) | 2019.08.02 |