본문 바로가기
컴퓨터/C, C++

[C/C++] 백준 2447번 C언어

by stdFrog 2022. 6. 11.

백준 2447번

 

재귀적인 패턴으로 별을 찍어 보자. 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번째 줄까지 별을 출력한다.

 

#include <stdio.h>

// 출력 문자 가지수
char arStar[2]={'*', ' '};

// BOOL 타입 정의
typedef enum {FALSE, TRUE} BOOL;

BOOL Space(int i, int j){
        /*
            본문의 "크기 N의 패턴은 공백으로 채워진 가운데의 (N/3)×(N/3) 정사각형을
            크기 N/3의 패턴으로 둘러싼 형태이다."는 다르게 말하면 다음과 같다.
            
            " N크기의 정사각형에서 중앙 (N/3)*(N/3)은 공백이어야 하며,
            최초, 공백 문자가 출력되는 시점은 (N/3)x(N/3) 이다. "
        */
        
        // 3x3크기의 정사각형에선 (1,1)에 빈 문자열 == (N/3) x (N/3)
        // 9x9크기의 정사각형에선 (3,3)에 빈 문자열 == (N/3) x (N/3)
        // ....
        
        // 예시를 보면, 3x3크기의 정사각형마다 중앙 (1,1)에 빈 문자열을 출력하는 패턴이 반복되고 있다.
        // 이 패턴에 의해 전체 사각형을 이루고 있으니 우리가 구해야될 값은 결국 (1,1)이다.
        
        // 아래는 그 코드이다.
        
        // 식을 간단하게 하기 위해 시작값(x,y)은 0으로 했다.
        // 입력값 N, 상수값 3, 매칭 값 1 - (x/N)%3==1
        for(i,j; i>0; i/=3, j/=3){
                if(i%3==1&&j%3==1){
                        return TRUE;
                }
        }
        return FALSE;
}

void RectAngle(int N){
        // i = 세로(y), j = 가로(x)
        for(int i=0; i<N; i++){
                for(int j=0; j<N; j++){
                        if(Space(i,j)){
                                printf("%c", arStar[1]);
                        }
                        else{
                                printf("%c", arStar[0]);
                        }
                }
                printf("\n");
        }
}

int main()
{
        int N;
        scanf("%d", &N);

        // 그리기 함수
        RectAngle(N);
}

 

 글 본문과 위 코드 블록에 적어둔 주석을 조금 수정했습니다. - (22.11.03)

 

글을 작성할 당시에는 몰랐는데 지나고보니 혼자서만 알아볼 수 있게 써놨더군요. 해서, 시간이 많이 지났지만 몇 가지 수정해서 다시 게시했습니다.

 

본문:

 NxN 정사각형은 (N/3)x(N/3) 좌표부터 (N/3)*(N/3)크기의 공백 문자를 출력하는 패턴을 갖고 있습니다.

 

 N은 3의 거듭제곱인 3, 9, 27... 이 입력되며, 이 N크기의 정사각형은 최소 단위인 3x3 크기의 패턴을 반복하여 모양을 이룹니다.

 

 3x3 크기의 정사각형에서 빈 문자열을 출력하는 좌표는 (3/3)x(3/3)인 (1,1)이며, 이를 코드로 표현하면 다음과 같습니다.

 

scanf("%d", &input);

for(int i=0; i<input; i++){
	for(int j=0; j<input; j++){
    	if( (input/3)==i && (input/3) == j){ // i와 j가 모두 1이면 공백 출력
        	printf(" ");
        }else{
        	printf("*");
        }
    }
    printf("\n");
}

 

 그런데, 입력값으로 3이 아닌 9나 27과 같은 3의 거듭제곱이 주어졌을 때에는 위 연산만으로 패턴을 반복할 수 없습니다.

 

 또한, 위와 같이 입력값(input)을 직접 참조하는 것보단 현재 좌표 즉, i와 j를 참조하여 이 값이 (1,1)이 되는지 확인해주는게 좋습니다.

 

 자세한 풀이는 글 상단의 코드 블럭을 참고하시기 바랍니다.

 

짧게 끝내겠습니다

감사합니다.

반응형

'컴퓨터 > C, C++' 카테고리의 다른 글

[C/C++] 백준 7568번 C언어  (0) 2022.06.14
[C/C++] 백준 2231번 C언어  (0) 2022.06.14
[C/C++] 백준 17478번 C언어  (0) 2022.06.09
[C/C++] 백준 10870번 C언어  (0) 2022.06.09
[C/C++] 백준 10872번 C언어  (0) 2022.06.09

댓글