본문 바로가기
카테고리 없음

[백준/C,C++] 10993번: 별 찍기 - 18

by 이민훈 2021. 5. 18.

https://www.acmicpc.net/problem/10993

 

10993번: 별 찍기 - 18

예제를 보고 규칙을 유추한 뒤에 별을 찍어 보세요.

www.acmicpc.net

풀이

 

위 그림처럼 별을 찍으면 되는 문제입니다.

 

재귀를 이용해 별을 찍는 문제들에서 배열에 값을 저장한 후 찍는 것이 아닌

 

해당 좌표에 '*' 이 출력돼야 하는지 공백이 출력돼야 하는지 바로 판단하여

 

출력하는 식으로 함수를 구현하려고 했고, 이번 문제 또한 배열을 쓰지 않는 방법으로 해결하였습니다.

 

 

가장 큰 삼각형 단계부터 가장 작은 삼각형 단계까지 재귀 호출합니다.

 

해당 좌표가 현재 삼각형 단계에서 '*' 로 출력될 자리인지 판단하고

 

아니라면 다음으로 작은 삼각형 단계로 재귀 호출하는데, 1 크기의 삼각형이 될 때까지

 

'*' 로 출력될 자리가 아니라면 공백을 출력합니다.

 

 

해당 문제를 풀 때 유의해야 할 점이 있는데 가장 큰 삼각형의 넓이까지만 문자를 출력해야 합니다.

 

아래 이미지들은 4가 입력됐을 때 각 4, 3, 2, 1단계까지만 재귀 호출한 출력 결과를 나타냅니다.

 

?은 아직 해당 좌표에 문자가 정해지지 않았음을 의미합니다.

 

 

 

 

 

 

#include<iostream>
#include<cmath>

using namespace std;

int mid;

void star(int y, int x, int num, int top, int bot)
{
    // 좌변과 우변의 위치
    int left = mid - abs(top - y);
    int right = mid + abs(top - y);
    // y좌표가 하단과 같고 x좌표가 좌변과 우변 범위안에 속해있다면 '*' 출력
    if (y == bot && x >= left && x <= right) cout << '*';
    else if (x == left || x == right) {
        // x좌표가 좌변과 우변의 위치와 같고 y좌표가 상단과 하단 범위안에 속해있다면 '*' 출력
        if ((top > bot ? top : bot) >= y && (top < bot ? top : bot) <= y) cout << '*';
        // 아니라면 공백 출력
        else cout << ' ';
    }
    else {
        // 어디에도 속하지 않는 부분은 공백 출력
        if (num == 1) cout << ' ';
        // 상단과 하단 위치를 갱신하여 재귀 호출
        else star(y, x, num - 1, num % 2 == 0 ? bot + 1 : bot - 1, (top + bot) / 2);
    }
}

int main(void)
{
    int n; cin >> n;
    int height = pow(2, n) - 1;
    int width = height * 2 - 1;
    mid = width / 2;

    for (int i = 0; i < height; i++) {
        for (int j = 0; j < (n % 2 == 0 ? width - i : width - (mid - i)); j++) {
            // 제일 큰 삼각형의 형태가 역삼각형이라면
            if (n % 2 == 0) star(i, j, n, height - 1, 0);
            // 아니라면
            else star(i, j, n, 0, height - 1);
        }
        cout << '\n';
    }

    return 0;
}

댓글