재귀 10

[백준 1992] 쿼드트리 [Python]

풀이 처음에 주어진 입력이 모두 0이거나 1일 경우 '0' 또는 '1'이 정답이 되지만, 위의 경우가 아닌 경우 사분면을 'Z' 순서대로 살펴보며 주어진 영역에 대해 모두 하나의 값이 존재할 때까지 recursive call 방식으로 풀이하면 된다. 문제에서 주어진 예제를 살펴보자. 색 (빨 - 주 - 연) 순서대로 분할할 것이며, 색상별 동그라미는 각 분할 시점의 기준 좌표가 된다. 기준좌표에 recursive를 거쳐 줄어든 크기(size)만큼의 영역에 대해 다시 탐색을 시도해 나가며 풀이하면 된다. 참고로 입력의 제한 중 다음과 같은 조건이 있기 때문에 "N은 언제나 2의 제곱수로 주어지며" recursive할 영역을 무조건 2로 나누어 범위를 재설정하면 된다. 소스코드 소스코드 보기 출처 1992번..

[백준 5639] 이진 검색 트리 [C]

풀이 조건에 맞게 값을 넣어줄 수 있는 Binary Search Tree를 구현하는 문제이다. 소스코드 #include #include typedef struct node{ int data; struct node *left, *right; }*pNode; void postorder(pNode root){ if (root == NULL) return; postorder(root->left); postorder(root->right); printf("%d\n", root->data); } pNode make_tree(pNode root, int data){ if (root == NULL){ root = (pNode)malloc(sizeof(pNode)); root->data = data; root->left..

[백준 1780] 종이의 개수 [C]

풀이 9등분을 하고, n/3만큼 좌표를 (x, y) 증가시켜 Divide and Conquer 하면 된다. N만큼의 종이가 모두 같을 때, 탐색을 중단해야 하므로 중단 조건을 함수로 만들어 풀이했다. 소스코드 #include int paper[2187][2187], I[3]; int all_same_paper(int x, int y, int n){ int temp = paper[x][y]; for (int i = x; i < x+n; i++) for (int j = y; j < y+n; j++) if (paper[i][j] != temp) return 0; return 1; } void division(int x, int y, int n){ if (all_same_paper(x, y, n)) I[pape..

[백준 17478] 재귀함수가 뭔가요? [C]

소스코드 #include int N; const char *str[7] = { "\"재귀함수가 뭔가요?\"", "\"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.", "마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.", "그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어.\"", "\"재귀함수가 뭔가요?\"", "\"재귀함수는 자기 자신을 호출하는 함수라네\"", "라고 답변하였지." }; void message(int n){ for (int i = 0; i < 4; i++){ for (int j = 1; j < n; j++) printf("____"); puts(str[i]); } if (n..

[백준 10993] 별 찍기 - 18 [C]

풀이 별로 만들어지는 삼각형의 높이와 너비는 각각 2^(N) -1, 2^(N+1) -3이다. 다음은 N=3일 때의 예제이다. 빨간 사각형은 mark_star(x, y, n)을 Recursive Call할 때 해당하는 영영이고, (x, y)는 맨 좌측상단이며, N=1때 는 (x, y)와 영역이 일치하므로 별을 찍어주고 함수를 종료한다. 연두색과 하늘색 공간의 별은 다음과 같이 찍었다. for (int i = 0; i < width; i++) arr[x+(n%2 ? height-1 : 0)][y+i] = '*'; // 연두색 for (int i = 0; i < height; i++){ if (n%2) arr[x+i][y+width/2-i] = arr[x+i][y+width/2+i] = '*'; // 하늘색 ..

[백준 2630] 색종이 만들기 [C]

풀이 입력받은 N을 이용해 정사각형을 분할하면서 전부다 1 또는 0일때까지 탐색을 하면 된다. 소스코드 #include int paper[128][128], w, b; void color(int x, int y, int n){ int cnt = 0; for (int i = x; i < x+n; i++) for (int j = y; j < y+n; j++) paper[i][j] && cnt++; if (cnt == n*n)b++; else if (!cnt) w++; else { color(x, y, n/2); color(x, y+n/2, n/2); color(x+n/2, y, n/2); color(x+n/2, y+n/2, n/2); } } int main(){ int N; scanf("%d", &N); f..

[백준 1074] Z [C]

풀이 사분면을 탐색해 방문횟수를 반환하는 방식보다는, 전체 허용 범위내 조건 충족시 출력을 하는 방식으로 풀이했다. 허용 범위가 아니라면, 다른 사분면에 있으므로 n*n을 누적해준다. 소스코드 #include int r, c, cnt; void Z(int row, int col, int n){ if (row == r && col == c){ printf("%d\n", cnt); return; } if (r >= row && c >= col && r < row + n && c < col + n) { Z(row, col, n/2); Z(row, col + n/2, n/2); Z(row + n/2, col, n/2); Z(row + n/2, col + n/2, n/2); } else cnt += n*n; } ..

[백준 2448] 별 찍기 - 11 [C]

풀이 출력 할 삼각형의 맨 위의 좌표(빨간 원)를 (0, N-1)이라고 하자. 이진트리 처럼 좌측 하단 삼각형의 맨 위 좌표(왼쪽 초록 원)는 (0 + N/2, N-1 - N/2), 우측 하단 삼각형의 맨 위 좌표(오른쪽 초록 원)는 (0 + N/2, N-1 + N/2)이다. 분할정복을 시행할 때마다, 입력받은 크기를 2로 나누어 건네주며, 전달받은 크기가 3이 될 때 배열에 빨간원 - 좌측 초록원 - 우측 초록원 이 순서대로 가장 작은 삼각형 내부에 별을 채워 넣는 것이다. 출력형식에 약간의 장난(?)이 숨어있다. 예제 출력을 드래그 해보니, 각 행의 마지막 별을 찍고 개행이 아니라, 공백을 출력해줘야 한다. memset()를 사용해 배열을 빠르게 초기화하고, 별을 채워 넣자. 소스코드 #include..

[백준 2447] 별 찍기 - 10 [C]

풀이 좌표를 이용해 문제를 해결하기로 했다. N = 9일 때, N(9)/3의 패턴으로 둘러싸인 공백의 좌표는 (3, 3), (3, 4), (3, 5), (4, 3), (4, 4), (4, 5), (5, 3), (5, 4), (5, 5)이다. 이 좌표들은 N(9)/3으로 나누면, 1.xx인 점을 이용해 공백을 찍으면 된다. N(9)/3의 패턴 속의 공백들의 좌표는 (1, 1), (1, 4), (1, 7), (4, 1), (4, 4), (4, 7), (7, 1), (7, 4), (7, 7)이다. 이 좌표들은 "parameter로 받아오는 3으로 나누어진 N값"이 조건을 성립하지 않아 N = 1이 될 때까지 계속 재귀함수를 호출하며, 결국 조건을 성립해 공백을 찍으면 된다. 이외의 좌표들은 "parameter..