본문 바로가기

algorithm/백준알고리즘

[백준알고리즘] 2447번: 별 찍기 - 10 -C++

728x90

[백준알고리즘] 2447번: 별 찍기 - 10 -C++

2447번: 별 찍기 - 10 (acmicpc.net)

 

2447번: 별 찍기 - 10

재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다. 크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이

www.acmicpc.net

별 찍기 문제 10번이다.

 

예전에 파이썬으로 푼 적이 있었다. 아래는 그때 풀었던 파이썬 풀이 링크다

[백준알고리즘] 2447번: 별 찍기 10 -Python (tistory.com)

 

이번에 풀 때도 마찬가지로 *로 채워진 전체 판에서 삭제할 부분을 선택했다.

그래서 로직 자체는 쉽게 재귀로 생각해서 풀렸는데.... 알 수 없는 오류들에 휘말렸었다.

 


 

먼저, 아래와 같이 코드를 작성해서 동적으로 n x n 크기의 char 이중 배열을 만들고 *로 초기화를 시켜주려고 했다. 

char** board = new char* [n];
for (int i = 0; i < n; i++)
	board[i] = new char[n];
std::fill_n(board, n * n, '*');

위의 코드로 인해서 아래와 같은 오류가 떴다.

빌드 자체가 되지 않음..

처음에는 왜 떴는지 전혀 감이 잡히지 않았는데 board에는 char 값이 아닌 char 동적 배열에 대한 주소값이 들어가 있기 때문에 오류가 발생한 것 같다. 정적 배열이었다면 fill_n을 통해 처음 작성했던 방법대로 작성해도 오류가 없을 것 같다.

 

아무튼 그래서 이 문제를 해결해주기 위해 board[i]에 char 배열을 동적 생성해 할당할 때 각 board[i]마다 초기화를 진행해주었다.

 


 

이 문제를 해결하니 다음 문제가 나왔다.

빌드되고 실행된다고 마냥 좋아했는데..... 출력 결과가 다음과 같이 나왔다.

 

뒤에 쓰레기 값이 붙는다..

출력을 다음과 같이 board[i]마다 char 배열을 한 줄 그대로 cout에 넣었더니 뒤에 NULL 값이 없어 쓰레기 값이 나오는 것으로 보였다.

for (int i = 0; i < n; i++)
    std::cout << board[i] << std::endl;

그래서 결국 이중 for문을 돌면서 각 위치의 문자를 출력해주었다.

 

다만, 이중 for문을 도면서 계속해서 cout을 통해 출력하면 시간이 오래 걸릴 것 같아 <sstream>ostringstream 객체를 이용해 출력문을 만들어주고 한 번의 cout을 통해 출력했다.

 


 

아래는 최종적으로 통과한 코드다.

#include <iostream>
#include <sstream>

void solve(void);

int main(void)
{
	solve();
}

void erase(char**& board, int x, int y, int length)
{
	for (int i = x; i < x + length; i++)
		for (int j = y; j < y + length; j++)
			board[i][j] = ' ';
}

void make_blank(char**& board, int x, int y, int length)
{
	if (length == 1) return;

	int d = int(length / 3);
	for (int i = x; i < x + length; i += d)
		for (int j = y; j < y + length; j += d)
		{
			if (i == x + d && j == y + d)
			{
				erase(board, i, j, d);
				continue;
			}
			make_blank(board, i, j, d);
		}
}

void solve(void)
{
	int n;
	std::cin >> n;

	char** board = new char* [n];
	for (int i = 0; i < n; i++)
	{
		board[i] = new char[n];
		std::fill_n(board[i], n, '*');
	}

	make_blank(board, 0, 0, n);

	std::ostringstream oss;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
			oss << board[i][j];
		oss << std::endl;
	}
	std::cout << oss.str();

	for (int i = 0; i < n; i++)
		delete[] board[i];
	delete[] board;
}

 

잘못된 점이나 부족한 점 지적해주시면 감사하겠습니다

728x90