import sys
A = int(sys.stdin.readline())
print(4 * A)
믿기지 않겠지만 이거 내고 맞았음. ...근데 정답률을 보니 뭔가 숨겨진 함정이 있는듯 한데...? 설마 C언어는 풀이가 다른가?
아, 찾아보니 입력되는 수의 범위가 10의 9승까지란다. 이러면 일부 언어는 int로 하면 틀리고 롱롱 이런거 들어가야된다. 설마 C언어에 함정 있나 했더니 자바도 그러네. (파이썬은 롱롱 그런거 없음)
여담으로 저정도 수학 실력이면... 빡시게 공부하지 않는 이상 이과나 공대는 포기하는게 좋다. 일단 우리과도 미적 쓰는건 못봤지만 통계는 쓰거든. 물론 계산은 엑셀이나 R을 쓰겠지만 이게 뭐 하는 분석인가 정도는 알고 있어야 쓰지 않겠음? 예전에 일어쌤이 '번역기를 쓰려면 그 나라 말을 알고 있어야 한다'고 하셨던것처럼. 공업수학은 말할 것도 없고. 나비에-스톡스 방정식 이런건 저런 식으로 절대 못 푼다.
아무튼 이 문제가 어려운건 단순히 완전수 로직때문이 아니라 출력때문... 완전수 로직은 쉽다. 자기 자신을 제외한 모든 약수들의 합이 자기 자신과 같다는건 약수 전체 합이 자기 자신의 두배라 이거거든.
import sys
while True:
N = int(sys.stdin.readline())
if N == -1:
break
일단 이게 while True 나가는 조건인건 아시겠죠? 이 다음꺼 훅 들어오니까 대비 잘하시고.
import sys
while True:
N = int(sys.stdin.readline())
if N == -1:
break
# 나갓!
yaksu_list = []
for i in range(1, N+1):
if N % i == 0:
yaksu_list.append(i)
# 약수 픽
sum_yaksu = sum(yaksu_list)
yaksu_template = " + ".join(map(str,yaksu_list[:-1]))
if sum_yaksu == 2 * N:
print("{} = {}".format(N, yaksu_template))
else:
print("{} is NOT perfect.".format(N))
노션에 복붙했는데 탭 안지워져서 걍 한번에 썼다. 약수 리스트에 넣는것까지는 아실 듯 하니 그 밑에걸로 바로 넘어가자. 어떤 수가 완전수이면 k = 1 + m + n 이런 식으로 자기 자신을 제외한 약수들의 합으로 나타내야 한다. 근데 약수 개수가 암만 완전수여도 수바수인데 어떻게요? 맨 뒤에꺼 빼고 자르면 되지. 그래서 -1로 슬라이싱하고 ' + '로 조인 멕였다.
여기서 중요한건 약수 목록에 들어간 게 int라 바로 join이 안된다. 그래서 map으로 문자열로 변환한 다음 join했다는 거... 이거 빼먹으면 로직은 맞는데 오류나서 안됩니다 여러분. 그리고 완전수 판정 로직은 위에도 썼듯 자기 자신을 제외한 모든 약수의 합이 자기 자신과 같다=약수 싹 더하면 두배라 저렇게 한거임.
약수랑 배수는 앞 문제에서 뭔지 설명했으니 패스. 이 문제에서는 어떤 수의 약수를 찾고+그 약수 중 k번째 약수를 출력하면 되는 매우 간단한 문제이다. 간단하다면서 정답률이 49%인 이유는 이따 설명해드림.
import sys
N, K = map(int, sys.stdin.readline().split())
yaksu_list = []
일단 입력은 입력이고 약수를 담을 배열이 필요하다.
for i in range(1, N+1):
if N % i == 0:
yaksu_list.append(i)
그리고 로직도 이거면 된다. 약수는 나머지가 0이니까 나눠서 나머지가 0이면 리스트에 넣고
print(yaksu_list[K-1])
아! 인덱싱 번호때문에 정답률이 낮았구나! 끝! 이거 내야지!!
네 그런 당신을 틀렸습니다가 반길것입니다 휴먼.
인덱싱 번호도 번호인데 이 문제에는 매우 기가 막힌 함정이 숨어있다. 25의 약수 중 4번째로 큰 약수를 달라고 하면 어떻게 될 지 생각해본 적 있음?
컴퓨터가 미쳤습니까 휴먼? 함. 그리고 백준 문제에도 '만일 N의 약수의 개수가 K개보다 적어서 K번째 약수가 존재하지 않을 경우에는 0을 출력하시오.'라고 쓰여있다. 왜죠? 25는 약수가 1, 5, 25로 세개그등요. 아 망했네 이거 어떡하죠? 약수 배열이 있으니까 배열 길이보다 K가 길때 0을 출력하게 만들면 되나요?
try:
print(yaksu_list[K-1])
except:
print(0)
뭘 고민함 걍 예외처리 때리지. 어차피 이거 배열 길이보다 인덱싱 하는 게 길어서 IndexError 난거잖음? 그니까 1) k번째 약수를 출력하되 2) IndexError가 나면 0을 출력해라 라고 하는거다. 엑셀의 Iferror랑 비슷하다.
import sys
N, K = map(int, sys.stdin.readline().split())
yaksu_list = []
for i in range(1, N+1):
if N % i == 0:
yaksu_list.append(i)
try:
print(yaksu_list[K-1])
except:
print(0)
자 우리 일단 들어가기전에 약수랑 배수가 뭔지 알아보고 가자. 이거 초딩때 한거라 다 까먹은 분들 계십니다, 예...
약수는 어떤 수를 딱 나눠 떨어지게 나눌 수 있는 수이고, 배수는 어떤 수로 딱 나눠 떨어지게 나눌 수 있는 수이다. 생각해봅시다. 5는 10의 약수이고 반대로 10은 5의배수이다. 1000은 8의 배수이고(125로 떨어짐) 8은 1000의 약수이다. 가릿?
import sys
while True:
m, n = map(int, sys.stdin.readline().split())
그리고 입력에 몇줄 받는다 이런거 없고 0 0 들어올때까지 받잖아요? 이게 뭔 소리냐면 와일트루(while True) 쓰라는 얘깁니다. 걍 무한뺑뺑이 돈다 이거지. 그러면 뭐가 필요해요? 그죠 나갈 조건 설정해야죠.
import sys
while True:
m, n = map(int, sys.stdin.readline().split())
if m == 0 and n == 0:
break
elif m <= n and n % m == 0:
print('factor')
elif m >= n and m % n == 0:
print('multiple')
else:
print('neither')
자 급하니까 알아서 따라오십쇼. if문에 있는건 반복문 나가는 조건, 즉 0 0에 대한 로직이다. 0 0이 들어오면 나가라는 얘기다. 그리고 약수는 왼쪽이 오른쪽보다 작거나 같고 오른쪽으로 왼쪽을 나누었을 때 나누어 떨어지면(나머지가 0이면) 약수다. 배수는 왼쪽이 오른쪽보다 크거나 같고(근데 배수가 자기자신 포함이던가...) 왼쪽으로 오른쪽을 나누었을 때 나머지가 0이면 배수. 둘이 방향 반대입니다. 그리고 둘 다 아니면 무관.
솔직히 패턴 파악해야되는데 1, 2 다음에 뜬금없이 5가 나오면 어쩔 수 없다. 손으로 그려봐야지. 그래서 그렸습니다.
이렇게 봐도 모르겠다면 정상이다. 나도 1089가 제곱수인가 해서 울프램알파에 루트 때려보고 알았음. 하지만 여기에는 마치 히든보스마냥 숨겨진 패턴이 있다면 믿겨지는가? 에이 뭔 dog sound냐고? 아 일단 들어봐요.
굵은 글자를 잘 보자. 1을 넣으면 9가 나오는데 이건 3의 제곱이고 3은 2+1이다. 그리고 2를 넣으면 나오는 25는 5의 제곱이고 5는 2+1+2이다. 3을 넣으면 나오는 81은 9의 제곱이고 9는 2+1+2+4이다. 어? 이거 완전 등비수열? 그렇다. 초항이 1이고 공비가 2인 등비수열의 '합'을 2에 더한 다음 그걸 제곱하면 된다.
import sys
T = int(sys.stdin.readline())
cent_list = [25, 10, 5, 1]
for i in range(T):
change = int(sys.stdin.readline())
저 리스트는 내가 그냥 기억하기 쉬우라고 해둔거지 실제로 써먹지는 않음. 그나저나 이런 문제를 어디서 본 것 같다고요? 이거 그 예전에 설탕 배달하는데 5킬로 3킬로 맞췄던 그 문제랑 비슷하다. 그리디 알고리즘을 이용하는건데 이 알고리즘은 지금 당장 롸잇나우 정답일 수는 있어도 항상 정답은 아닌 그런 알고리즘이다. 그니까 지금은 어쩔 수 없었지만 나중에는 땅을 치고 후회하게 되는 뭐 그런 느낌인거다.
예를 들어서 나는 지금 너무 배고프고 주머니에 5000원이 있다고 치자. 그런데 마침 저기 타코야끼 트럭이 보인다. 그 옆에는 편의점도 있다. 그런데 타코야끼 트럭은 보니까 줄이 꽤 길어서 좀 기다려야 할 것 같고, 편의점은 꽤 한산해서 바로 계산이 된다. 근데 나는 지금 너어어어어어어어어어무 배가 고파서 웨이팅이 힘들다, 그러면 편의점 가서 뭘 먹는다.
이거 비슷한 케이스로는 소드실드 예약구매 하는 김에 스위치 같이 샀더니(배터리 개선판) 이듬해에 코로나 터져서 스위치 대란 터진거...? 그래서 본인 모동숲은 DL버전이다. 팩이 없으면 다운로드하면 된다 걍 필요해서 샀더니 본의아니게 신의 한수가 되었음...
import sys
T = int(sys.stdin.readline())
cent_list = [25, 10, 5, 1]
for i in range(T):
quarter = 0
dime = 0
nickel = 0
penny = 0
change = int(sys.stdin.readline())
while change >= 25:
change -= 25
quarter += 1
while change >= 10:
change -= 10
dime += 1
while change >= 5:
change -= 5
nickel += 1
penny += change // 1
print(quarter, dime, nickel, penny)
일단 딱히 뾰족한 수가 없어서 걍 while 때려박았다. 자, 생각해봅시다. 어떤 수가 25, 10, 5, 1로 나누어 떨어지지 않으려면 그 수보다 작아야 한다. 그러니까 25보다 큰 수는 일단 25로 나누고, 그 나머지를 10으로 나누고, 그 나머지를 5로 나누고, 그 나머지는 어차피 1의 자리이기 때문에 1의 자리에 걍 더하면 된다.
예를 들어서 124센트를 줘야 한다... 그러면 25보다 작은 수가 될 때까지 25를 계속 뺀다. 그러면 25를 네 번 빼면 남는건 24니까 25센트짜리는 4개가 된다. 다음으로 10보다 작은 수가 될 때까지 24에서 10을 계속 뺀다. 그러면 10센트 두 개를 빼고 4가 남고, 5보다 작을때까지 5를 빼야 하는데 이미 5보다 작기때문에 걍 페니 4개가 나오게 된다.
그리고 저번 문제에서 봤던 이분이 또 왔다. 위 리스트는 아스키코드 번호고 아래는 10~35까지가 들어있는데, 저번 풀이에서는 알파벳을 아스키코드 번호로 바꿔서 숫자를 찾았다면 이번에는 역으로 숫자로 알파벳의 아스키코드를 찾아서 알파벳으로 바꿔서 출력할거다.
import sys
a, N = map(int, sys.stdin.readline().split())
over_ten_list = list(range(65,91))
over_ten_number = list(range(10,36))
jinsu_list = []
while a >= 1:
jinsu_list.append(a % N)
a = int(a / N)
jinsu = jinsu_list[::-1]
jinsu = ''.join(map(str,jinsu))
print(jinsu)
중요한게 하나 더 있다. 본인 풀이글을 봐 오신 분들은 아시겠지만 for문 가는데 while이 국룰이라고, 리스트 컴프리헨션 말고 어지간한 반복문으로 푸는 건 다 for버전과 while버전이 있는데 이건 while만 있다. 그리고 깃헙에 올린 코드도 while만 있다. 왜냐하면 얘는 더 이상 진수변환할 수 N으로 나누어 떨어지지 않을때까지만 해야 하거든...
2진수의 경우 최종적으로 몫이 1이 되면 중단하고, 16진수의 경우 몫이 15 이하가 되면 중단한다. 예를 들어서 31을 16진수로 변환한다면 처음에 31을 16으로 나눈 나머지, 즉 15가 리스트에 먼저 들어가게 된다. 그리고 나눠놓고 보니 몫이 1이네? 그럼 더 나눠봐야 뭐 나올게 없잖음. 그래서 jinsu_list에는 15, 1이 들어가게 된다.
while a >= 1:
if a % N < 10:
jinsu_list.append(a % N)
else:
jinsu_list.append(chr(over_ten_list[over_ten_number.index(a % N)]))
a = int(a / N)
그리고 여기서 필요한게 바로 이 부분이다. 위에서 31을 16진수로 바꾸기 위해 나눴을 때 리스트에 15, 1이 들어간다고 했는데 진수 변환할 때 10부터는 상응하는 알파벳을 사용한다. A부터 Z까지가 10~35인데, 위에서 설명했듯 1) N으로 나눈 나머지가 10보다 작으면 그냥 리스트에 넣고, 아니면 2) 숫자 목록에서 해당하는 숫자가 몇 번째인지 찾아서 3) 그 순서 그대로 아스키코드 리스트에서 찾은 다음 4) chr() 때려박아서 알파벳을 저장한다.
한가지 더 짚고 넘어갈 부분이 있다. 31은 16진수로 1F가 맞는데(32가 20) 위에서 배열에 들어간 순서가 15(F), 1이니까 순서를 뒤집어줘야 한다. (진법 변환할때는 밑에서 위로 가는데 리스트에 넣는 순서는 위에서 밑으로 넣는다) 그리고 리스트니까 걍 뽑으면 [1, 'F']가 될 거 아녀? 그래서 다 떼버리고 안에 있는 요소를 .join으로 붙여주는거다. 문자열로 만들어서 붙여준 다음 출력하면 profit!
import sys
a, N = map(int, sys.stdin.readline().split())
over_ten_list = list(range(65,91))
over_ten_number = list(range(10,36))
jinsu_list = []
while a >= 1:
if a % N < 10:
jinsu_list.append(a % N)
else:
jinsu_list.append(chr(over_ten_list[over_ten_number.index(a % N)]))
a = int(a / N)
jinsu = jinsu_list[::-1]
jinsu = ''.join(map(str,jinsu))
print(jinsu)
일단 n진수를 10진수로 변환할때는 일의자리부터 1, n, n^2, n^3, ...이런 식으로 곱한 다음 더하면 된다. (0이면 패스) 10진수를 n진수로 바꿀 때는 n으로 더 이상 나누어 떨어지지 않을 때까지 나눈 다음 위 그림처럼 쓰면 된다. 10진수 이상일 경우 나머지가 10 이상일 때도 있는데 그건 알파벳 A부터 시작하면 된다. 16진수의 경우 A, B, C, D, E, F 순서대로 10, 11, 12, 13, 14, 15.
2, 8, 16진수 상호변환은 1) 뒤에서부터 세자리씩 끊어서 10진수로 변환(2->8), 2) 뒤에서부터 네자리씩 끊어서 10진수로 변환하고 10 이상은 해당하는 알파벳으로 변환(2->16), 3) 2진수로 변환 후 해당하는 자릿수만큼 끊어서 10진수로 변환(8<->16)하면 된다.
저거 풀면서 역변환 코딩한 거 있는데 그건 따로 털어드림. 역변환 따로 한 건 진수가 고정되어있는데 이번 문제는 2부터 36까지 범위가 지정된 변수이다. 그니까 3진수 9진수 이런거 들어올수도 있다 그죠? 그럼 어카냐고? 입력이 두 개가 되는거죠.
A~Z가 10~35까지라고 나와있는데 왜 두 리스트가 다 숫자가 들어가있냐고? 그건 로직에서 설명드림.
import sys
a, N = sys.stdin.readline().split()
N = int(N)
cipher = len(a)
a = a[::-1]
dec_number = 0
over_ten_list = list(range(65,91))
over_ten_number = list(range(10,36))
for i in range(cipher):
try:
dec_number += int(a[i]) * (N ** i)
except:
dec_number += over_ten_number[over_ten_list.index(ord(a[i]))] * (N ** i)
print(dec_number)
여기서 키포인트는 두개다. 첫번째는 예외처리이고 두번째가 ord()인데...
1. 애초에 파이썬으로 입력 받자마자는 내가 숫자를 쓴거건 문자로 쓴거건 자료형이 문자열이다. 그럼 int로 변환해야 뭘 계산하든가 말든가 하잖음? 문자열 그대로 계산하면 컴퓨터가 미쳤습니까 휴먼? 한다. 그런데 숫자가 아닌 알파벳을 int로 변환하려고 하면? 또 미쳤습니까 휴먼? 한다. 그리고 알파벳은 뭐가 있어요? 그죠 아스키코드 번호 있잖아. 입력이 대문자인데 65~90까지가 대문자 알파벳을 지정하네? (LA에서 잡은 안농 이름이 저거)
2. 저 리스트가 알파벳 대문자 아스키코드에 해당하는 번호가 들어간 리스트니까 ord()로 변환해서 리스트에서 몇번째인가를 찾고, 다시 그걸로 해당하는 숫자 리스트에서 인덱싱하면 숫자가 나오잖음. ASCII 리스트로 범위 만든거니까 일일이 타이핑하는 수고로움도 줄었다 이거죠.
그래서 1) 입력받은 문자를 하나씩 숫자로 변환해서 곱하되 2) 변환 못하는거면(알파벳이면) 리스트에서 아스키코드 번호로 찾아서 3) 해당하는 숫자 곱해라 가 된거임. 와 천잰데귀차니즘이 이렇게 유용합니다
와 3.2... 나 3.0 안되는데 개부럽네... 아무튼... 이 문제 보자마자 뇌에서 블루스크린이 떴다면 정상이다. 나도 떴거든.
일단 전공 평점을 어떻게 구하는건가... 보니까 전공과목별 (학점 × 과목평점)의 합을 학점의 총합으로 나눈 값이라고 한다. 근데 예제가 20개라 감이 안 오니까 이걸 뭘 어쩌하는건가... 했다가... 결국 엑셀을 소환했음.
계산 과정
예제를 텍스트 파일로 저장한 다음 엑셀로 불러오면 이렇게 지가 알아서 나눠준다. 그리고 학점 변환하는 표도 가져오면 된다. 근데 P/F가 패스논패스인가? 패스논패스면 학점 저렇게 많이 안주던데… 울학교 채플이 패스논패스인데 학점 1학점임. 아, 모르셨군요. 세종대 미션스쿨임.
그러면 학점 표를 갖다가 A+ A0 이런걸 변환을 해 줘야 하는데 vlookup을 사용하면 된다. ...정확히는 그것만 갖고 하면 P를 못 찾아서 오류가 나는데, 어차피 패스논패스는 계산에서 빠지니까 iferror로 공백 주면 된다. 즉, iferror(vlookup())으로 변환한거다.
P/F는 학점총계에서도 빼야 한다. 즉, 입력받는 과목의 학점이 P면 계산에서 아예 제한다. 근데 F면 짤없이 0점 주던데… 그건 둘째치고 패스논패스 과목은 출첵만 잘 해도 점수 거저 먹는건데 그걸 논패스를 떠? 이거 미쳤구만?
다시 풀이로
import sys
for i in range(20):
gwamok, hakjeom, grade = sys.stdin.readline().split()
일단 입력을 받으면 전부 문자열이라 계산이 안되니까 hakjeom(학점)을 float로 바꿔주자. 왜 float냐면 예제에서 표기가 그랬어요...
import sys
total_grade = 0
total_hakjeom = 0
grade_list = ['A+',"A0","B+","B0","C+","C0","D+","D0","F"]
grade_point = [4.5,4.0,3.5,3.0,2.5,2.0,1.5,1.0,0.0]
for i in range(20):
gwamok, hakjeom, grade = sys.stdin.readline().split()
hakjeom = float(hakjeom)
뭐가 많이 늘었는데 이게 다 변환하는데 필요한건가요? 놉. 그건 밑에 float()에 있는거 하나다. total 어쩌고 변수는 나누기 할 숫자 계산할 변수다. total_grade에는 학점*평점(과목평점)이, total_hakjeom에는 학점총계가 들어간다. 밑에 있는 리스트는 일단 보다보면 뭔지 알게 될것이다.
for i in range(1):
gwamok, hakjeom, grade = sys.stdin.readline().split()
hakjeom = float(hakjeom)
if grade in grade_list:
print(grade_point[grade_list.index(grade)])
위에 있는 리스트 두 개는 문제에서 제시해준 학점 표를 배열로 만든 것이다. 그래서 입력받는 점수 중에 평점이 P가 아닌 과목들에 대해서 평점 목록의 인덱스 번호를 불러와서 평점 점수 리스트에서 그걸로 그대로 인덱싱할거다. 물론 print문이 들어간 건 테스트 차원에서 그런거고, 저렇게만 해두면 P가 들어왔을 때 미쳤습니까 휴먼? 할 수 있기 때문에 거기에 대한 처리도 해줘야 한다.
import sys
total_grade = 0
total_hakjeom = 0
grade_list = ['A+',"A0","B+","B0","C+","C0","D+","D0","F"]
grade_point = [4.5,4.0,3.5,3.0,2.5,2.0,1.5,1.0,0.0]
for i in range(2):
gwamok, hakjeom, grade = sys.stdin.readline().split()
hakjeom = float(hakjeom)
if grade in grade_list:
total_hakjeom += hakjeom
total_grade += hakjeom * grade_point[grade_list.index(grade)]
else:
continue
print(total_grade, total_hakjeom)
난 아직도 컨티뉴와 패스가 뭔 차이인지 모르겠음...
아무튼 반복문에서 컨티뉴는 다음 순번으로 넘어가라는 의미이다. 즉, 평점이 P이면 계산이고 뭐고 안 하니까 걍 다음걸로 넘어가게 되는거다. 20개의 과목을 입력한다 치면 1번부터 쭉 들어오는데, 그 중 10번 과목이 P이면 걍 11번 받으라는 얘기.
import sys
total_grade = 0
total_hakjeom = 0
grade_list = ['A+',"A0","B+","B0","C+","C0","D+","D0","F"]
grade_point = [4.5,4.0,3.5,3.0,2.5,2.0,1.5,1.0,0.0]
for i in range(20):
gwamok, hakjeom, grade = sys.stdin.readline().split()
hakjeom = float(hakjeom)
if grade in grade_list:
total_hakjeom += hakjeom
total_grade += hakjeom * grade_point[grade_list.index(grade)]
else:
continue
print(total_grade / total_hakjeom)
import sys
total_grade = 0
total_hakjeom = 0
grade_list = ['A+',"A0","B+","B0","C+","C0","D+","D0","F"]
grade_point = [4.5,4.0,3.5,3.0,2.5,2.0,1.5,1.0,0.0]
for i in range(20):
gwamok, hakjeom, grade = sys.stdin.readline().split()
hakjeom = float(hakjeom)
if grade in grade_list:
total_hakjeom += hakjeom
total_grade += hakjeom * grade_point[grade_list.index(grade)]
else:
continue
total_grade = total_grade / total_hakjeom
print(f'{total_grade:.6f}')
는 이걸로 한방에 통과했구연.
참고로 졸업 요건은 학바학이긴 한데 보통 학점총계에 플러스 알파가 있다. 일단 우리학교는 평점 제한은 없었음. 나때는 120학점 이상(18학점 꾸준히 듣는다는 전제하에 4학년 2학기가 널럴해짐)+토익점수(대체과목 인정) 이렇게 있었는데 요즘은 토익 점수 커트라인도 올라가고 고전독서? 그것도 들어야 하는 모양임. 토익점수는 영문과가 더 높았던걸로 기억함.
이거 일단 잘 따라오십쇼... 중간에 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 안 더하면 저 코드 안끝납니다. 쟤는 조건부 반복문이라 나갈 조건을 충족해야 나가요.
import sys
T = int(sys.stdin.readline().rstrip())
for i in range(T):
word = sys.stdin.readline().rstrip()
print(word[0], word[-1])
첫글자면 0번 뽑으면 되는데 끝글자를 어떡하지? len() 줘서 그걸로 뽑을까? 놉. 그거 또 하나 빼야되지 않음? 아니 그런거 고민할 바에 걍 -1 줘버려요. -1번째 인덱싱하면 걍 맨 끝에꺼 나옴. 근데 어 됐다 하고 저거 내면 틀립니다. 있어봐. 아직 형식 안 잡았다. 예시 출력에서는 AB 이런 식으로 붙어있었는데 저거 출력하면 공백 하나 있잖음.
import sys
T = int(sys.stdin.readline().rstrip())
for i in range(T):
word = sys.stdin.readline().rstrip()
print('{}{}'.format(word[0],word[-1]))