#BOJ 2447 별찍기 - 10

Wonder_Why (Today I learned)·2022년 1월 21일
0

BOJ

목록 보기
37/70

✨별찍기 - 10

시간 제한	메모리 제한	제출	정답	맞힌 사람	정답 비율
1 초	256 MB	42410	22165	16372	52.235%

문제
재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다.

크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이 하나씩 있는 패턴이다.

***
* *
***

N이 3보다 클 경우, 크기 N의 패턴은 공백으로 채워진 가운데의 (N/3)×(N/3) 정사각형을 크기 N/3의 패턴으로 둘러싼 형태이다. 예를 들어 크기 27의 패턴은 예제 출력 1과 같다.

입력

첫째 줄에 N이 주어진다. N은 3의 거듭제곱이다. 즉 어떤 정수 k에 대해 N=3k이며, 이때 1 ≤ k < 8이다.

출력

첫째 줄부터 N번째 줄까지 별을 출력한다.

예제 입력 1
27

예제 출력 1

***************************
* ** ** ** ** ** ** ** ** *
***************************
***   ******   ******   ***
* *   * ** *   * ** *   * *
***   ******   ******   ***
***************************
* ** ** ** ** ** ** ** ** *
***************************
*********         *********
* ** ** *         * ** ** *
*********         *********
***   ***         ***   ***
* *   * *         * *   * *
***   ***         ***   ***
*********         *********
* ** ** *         * ** ** *
*********         *********
***************************
* ** ** ** ** ** ** ** ** *
***************************
***   ******   ******   ***
* *   * ** *   * ** *   * *
***   ******   ******   ***
***************************
* ** ** ** ** ** ** ** ** *
***************************

구현(1)

/*
BOJ : https://www.acmicpc.net/problem/2447
Recurssive, Divide & Conquer 별찍기-10
Versatile0010
*/

#include <bits/stdc++.h>
using namespace std;

void solve(int x, int y, int n) // x,y 좌표별로 n에 따라 올바른 문자 출력
{
	if (x / n % 3 == 1 && y / n % 3 == 1) // 공백을 출력해야 하는 경우
		cout << ' ';
	else if (n / 3 == 0) // * 을 출력해야 하는 경우
		cout << '*';
	else
		solve(x, y, n / 3); // 재귀호출
}

int main()
{
	int n; // 도형의 크기 입력받음
	cin >> n;

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{ // 좌표별로 순회하며 solve 함수에 넣어, 해당 좌표에 올바른 문자 * or ' ' 출력
			solve(i, j, n);
		}
		cout << '\n'; // 한 줄을 다 출력했으면 다음줄로
	}
	return 0;
}

구현(2)

/*
BOJ : https://www.acmicpc.net/problem/2447
Recurssive, Divide & Conquer 별찍기-10
Versatile0010
*/

#include <bits/stdc++.h>
using namespace std;

char star[2188][2188];
void setting(int x, int y, int n)
{
	if (n == 1) // 더이상 사이즈를 분할할 수 없으면
	{
		star[x][y] = '*'; // * 을 저장
		return;
	}
	else
	{
		int new_n = n / 3; // size를 1/3 로 축소
		int ifis5meansCenter = 0;
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++) // 1/3로 축소하면 총 9개의 구역이 생긴다.
			{// 9개의 구역을 순회하며 검사
				ifis5meansCenter++; // 해당 값이 5라는 것은 현재 가운데 구역을 탐색 중이라는 것
				if (ifis5meansCenter != 5)
				{
					setting(x + i * new_n, y + j * new_n, new_n); // 가운데가 아닐 때에만 재귀 호출
				}
			}
		}
	}
}
int main()
{
	int n; // 도형의 크기 입력받음
	cin >> n;

	for (int i = 0; i < 2188; i++)
		fill(star[i], star[i] + 2188, ' '); // 출력하기 전에 일단 공백으로 채워두고

	setting(0, 0, n); //원하는 크기만큼 도형을 미리 만듦

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			cout << star[i][j];
		}
		cout << '\n';
	}

	return 0;
}

GIT: https://github.com/versatile0010/PS

profile
전자과 머학생

0개의 댓글