문제
https://www.acmicpc.net/problem/2444
별찍기인데 이제 마름모꼴이다.
Reference
풀이
이거 일단 잘 따라오십쇼... 중간에 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 안 더하면 저 코드 안끝납니다. 쟤는 조건부 반복문이라 나갈 조건을 충족해야 나가요.
'BOJ > [BOJ] Python' 카테고리의 다른 글
백준 2745번 풀이 (0) | 2023.06.16 |
---|---|
백준 25206번 풀이 (0) | 2023.06.15 |
백준 10988번 풀이 (0) | 2023.05.30 |
백준 11718번 풀이 (0) | 2023.05.30 |
백준 9086번 풀이 (0) | 2023.05.30 |