컴퓨터 사이언스/1고리즘
백준 1030 : 프렉탈 평면
저세상 개발자
2021. 8. 10. 01:21
https://www.acmicpc.net/problem/1030
1030번: 프렉탈 평면
첫째 줄에 7개의 정수 s, N, K, R1, R2, C1, C2가 주어진다.
www.acmicpc.net
함수를 재귀호출하여 풀 수 있는 문제다.
이 문제에서 배열의 최대 범위가 x, y 각각 2^30으로 매우 크므로 해당 크기의 배열을 만들어서 갱신하는 것은 불가능하고 우리가 원하는 영역에 대해서만 갱신해준다.
1. 재귀 종결 조건은 cur_n이 1이거나 출력 범위에 아예 포함되지 않는 경우다.
2. 현재 cur_n에서 1로 마킹되어야 할 영역을 계산하고 마킹한다.
3. 영역별로 나누어 1로 마킹한 영역을 제외하고 영역별 시작 지점과 cur_n/n 값을 매개변수로 재귀호출한다.
#include <iostream>
using namespace std;
int s, n, k, r1, r2, c1, c2;
bool board[50][50];
long long cnt;
void fractal(int sx, int sy, int cur_n) {
//cur_n이 1이거나 출력 범위에 아예 포함되지 않을 시 리턴
if (cur_n <= 1 || sx > c2 || sy > r2 || sx + cur_n - 1 < c1 || sy + cur_n - 1 < r1)
return;
int next_n = cur_n / n;
int offset = (cur_n - next_n * k) / 2;
//1로 마킹될 영역
int kx_min = sx + offset, kx_max = sx + cur_n - offset;
int ky_min = sy + offset, ky_max = sy + cur_n - offset;
//1로 마킹될 영역 마킹
for (int y = ky_min < r1 ? r1 : ky_min; y < ky_max; y++) {
if (y - r1 > r2 - r1) break;
for (int x = kx_min < c1 ? c1 : kx_min; x < kx_max; x++) {
if (x - c1 > c2 - c1) break;
board[y - r1][x - c1] = 1;
}
}
//영역별 재귀호출
for (int y = sy; y < sy + cur_n; y += next_n) {
for (int x = sx; x < sx + cur_n; x += next_n) {
if (y >= ky_min && y < ky_max && x >= kx_min && x < kx_max)
continue;
fractal(x, y, next_n);
}
}
}
void solution() {
int max_n = 1;
cin >> s >> n >> k >> r1 >> r2 >> c1 >> c2;
for (int i = 0; i < s; i++) max_n *= n;
fractal(0, 0, max_n);
for (int y = 0; y <= r2 - r1; y++) {
for (int x = 0; x <= c2 - c1; x++) {
cout << board[y][x];
}
cout << '\n';
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
solution();
return 0;
}
메모리: 2024 kb | 시간: 0 ms |