백준 2444번 풀이

문제

별찍기인데 이제 마름모꼴이다.

Reference

https://hk713.tistory.com/6

풀이

이거 일단 잘 따라오십쇼… 중간에 100% 길 잃어먹고 이게 대체 뭔 개소린가 싶을거임.

이건 일단 백준에서 패턴을 다 떠멕여줬다. 뭐라고 했냐… 첫째 줄부터 2×N-1번째 줄까지 차례대로 별을 출력한다.라고 했다. 그니까 일반항 뭐다? 2N-1이죠. 그러면 별 찍을라면 range가 1부터 N+1까지 가야되는’데’… 이게 삼각형이면 그래도 되는데… 이거 마름모예요 여러분…

N = int(sys.stdin.readline().rstrip())
star_line = N * 2

그래서 변수가 두 개 들어간다. N은 입력값이고 분기점이 될 값이기도 하자. star_line은 전체 줄 개수로, 입력값 * 2 하면 range가 0부터 N * 2 – 1까지로 알아서 잡힌다. (5를 쓰면 0~9가 된다) 물론 이 range 이대로 잡으면 클나겠죠?

import sys 

N = int(sys.stdin.readline().rstrip())
star_line = N * 2

for i in range(1, star_line):
    max_star = N * 2 - 1
    current_star = 2 * i - 1
    if i <= N:
        print("*" * current_star)
    else: 
        print("*" * max_star)

그니까 range가 1부터 시작하면 5를 입력했을 때 1, 2, 3, 4, 5, 6, 7, 8, 9로 9줄이 나온다. (예시 세봤더니 9줄이었음) 그럼 분기점 정하는것도 이해 되셨죠? <=가 들어간건 일단 N번째 줄까지는 별이 중가하기때문에 그렇게 들어간거다. 아래는 ㄹㅇ 대공사도 이런 대공사가 없어요 세상에…

import sys 

N = int(sys.stdin.readline().rstrip())
star_line = N * 2

for i in range(1, star_line):
    max_star = N * 2 - 1
    current_star = 2 * i - 1
    if i <= N:
        print(" " * ((max_star - current_star) // 2), end="")
        print("*" * current_star)
    else: 
        print("*" * max_star)

위는 우리가 생각했던 ‘그’ 별찍기가 맞다. 가운데정렬을 하려면 별과 공백이 반비례해야 하는 것도 아시겠죠? 공백을 왜 저렇게 잡았냐면 첫째줄에는 별이 하나 들어가니까 공백이 4개가 온다. 그러면 9-1은 8이니까 나누기 2 하면 4잖음? 그런 식으로 아래로 갈수록 공백이 4, 3, 2, 1로 줄어간다. 별은 1, 3, 5, 7, 9로 늘어난다. 일단 분기점까지는 이해하셨죠?

import sys 

N = int(sys.stdin.readline().rstrip())
star_line = N * 2

for i in range(1, star_line):
    max_star = N * 2 - 1
    current_star = 2 * i - 1
    reflect_star = max_star - current_star
    if i <= N:
        print(" " * ((max_star - current_star) // 2), end="")
        print("*" * current_star)
    else: 
        print(" " * (-reflect_star // 2), end="")
        print("*" * (current_star + reflect_star * 2))

그럼 분기점을 넘어가면 다시 7, 5, 3, 1개가 되어야 하는데… (공백은 1, 2, 3, 4) 이걸 어떻게 뽑았느냐를 보려면 새로운 변수 reflect_star를 보면 된다. 얘는 max_star – current_star인데 잘 보면 위쪽에서 삼각형 만들때는 없던 변수이다. 즉, 이 변수는 순전히 아래쪽 별 만들기때문에 생겨난 변수다.

이 그림은 current_star, reflect_star 그리고 계산 완료된 별의 개수이다. 보면 max_star는 입력값 N에 따라 변하긴 하지만 그 값 자체는 정해져 있다. 예시 입력이 5면 max_star는 9로 고정된다. 그런데 current_star는 1부터 시작해서 위에 for문에 있는 range까지 값이 계속 증가한다. 1, 3, 5, 7, 9 다음에 11, 13, 15, 17까지 증가하는데 이렇게 되면 reflect_star는 위쪽 삼각형을 만들 때, 그러니까 i가 N보다 작을때는 양수지만 i가 N보다 커지면 음수가 된다. 즉, reflect_star를 양수로 만들고 2로 나누면 찍을 공백 숫자가 된다.

별 개수는 아래로 갈수록 적어지는데 이것도 마찬가지다. current_star가 커질수록 reflect_star도 커지게 되는데 6행의 경우 max_star가 9고 current_star가 11이니까 reflect_star는 -9가 되고, current_star에서 reflect_star의 두 배를 빼면 7이 된다. 이게 좀 어렵다면 max_star + reflect_star로 계산해도 OK. (최대 별 값은 고정되어있다는 사실을 기억합시다)

그래서 while로는 안되냐고?

N = int(sys.stdin.readline().rstrip())
star_line = N * 2

k = 1
while k <= star_line: 
    max_star = N * 2 - 1
    current_star = 2 * k - 1
    reflect_star = max_star - current_star
    if k <= N:
        print(" " * ((max_star - current_star) // 2), end="")
        print("*" * current_star)
        k += 1
    else:
        print(" " * (-reflect_star // 2), end="")
        print("*" * (max_star + reflect_star))
        k += 1

while은 각각 한줄씩 추가되었다. 1 안 더하면 저 코드 안끝납니다. 쟤는 조건부 반복문이라 나갈 조건을 충족해야 나가요.