입력은 크게 두 가지로, 제곱미터당 자라는 참외의 수와 방향/길이이다. 방향은 1, 2, 3, 4 순으로 동-서-남-북. 예시 입력을 보자면
이런 식이다. 참 쉽죠? 그러니까 계산할 사각형을 잘 잡아야 한다. 그럼 착수해봅시다.
일단 파이썬에서 이차원 배열은
rows = 5
cols = 5
arr = [[0 for i in range(cols)] for j in range(rows)]
print(arr)
이런 식으로 만든다. 근데 왜 이차원 배열이 나와요? 아니 그거 할거니까.
arr = [list(map(int,input().split())) for _ in range(6)]
print(arr)
배열이 꼭 정사각형만 된다는 편견은 버리자.
for i in range(len(arr)):
if arr[i][0] == 1 or arr[i][0] == 2:
if width < arr[i][1]:
width = arr[i][1]
width_index = i
print('w',width,width_index)
elif arr[i][0] == 3 or arr[i][0] == 4:
if height < arr[i][1]:
height = arr[i][1]
height_index = i
print('h',height,height_index)
배열을 토대로 이렇게 하면 가로세로로 제일 긴 변을 뽑을 수 있다. 인덱스가 필요한 이유는 나중에 얘기해드림. 위 코드는 방향(i번째 배열 0번)이 1, 2면 가로/3, 4면 세로로 분류하고 거기서 제일 긴 변의 길이와 인덱스를 변수에 저장하는 코드다.
시어핀스키 카펫은 프랙탈의 일종인데, 프랙탈은 그냥 똑같은 모양이 계속 반복되는 모양이다. 시어핀스키 카펫은 사각형을 9등분 한 다음 가운데를 지우고 그 사각형을 또 9등분해서 가운데 날리고 이런 식으로 반복되는 프랙탈의 일종. 이게 3차원이 되면 맹거 스펀지가 된다.
참고로 자매품으로 시어핀스키 삼각형도 있다. 이걸 코딩하라고 하면 개쌉고인물이 아닌 이상 힘들다.
일단 2번 풀이는 공간을 가로로 3등분하고 재귀함수를 통해 반복하는 형식이고(그래서 더 쉽다) 1번 풀이는 공간을 9등분 한 다음 5번째 공간을 공백으로 두는 방식이다. 그래서 배열이라는 개념이 나오는데… 어? 넘파이 있어야돼요? 아뇨 그러면 백준에서 빠꾸먹습니다…
arr1 = [['*' for i in range(3)] for j in range(3)]
for i in range(3):
for j in range(3):
print(arr1[i][j],end="")
print()
넘파이 없어도 배열 만들 수는 있다. 저기서 3을 n으로 바꾸면 n*n으로 배열을 만드는 것도 가능하다. 물론 2차원 좌표 지정이나 슬라이싱도 넘파이랑 비슷하게 할 수 있다. (arr[i][j] 이런 식으로)
import sys
sys.setrecursionlimit(10**6)
def star(row):
div3 = row // 3
if row == 3:
arr[1] = ['*', ' ', '*']
arr[0][:3] = arr[2][:3] = ['*'] * 3
return
star(div3)
for i in range(0, row, div3):
for j in range(0, row, div3):
if i != div3 or j != div3:
for k in range(div3):
arr[i+k][j:j+div3] = arr[k][:div3]
n = int(input())
arr = [[' ' for _ in range(n)] for _ in range(n)]
star(n)
for i in range(n):
for j in range(n):
print(arr[i][j], end='')
print()
row, 그러니까 입력한 값이 3일 때는 별별별 별 별 별별별이 출력된다. 엥? 근데 저 for문에 range는 뭔가요? 자, 입력을 9로 예시를 들면 0, 9, 3이 된다. (div3 = 입력값을 3으로 나눈 몫이니까 3) 그래서 0, 3, 6이 나오게 된다. 저기서 i가 3이 아니거나 j가 3이 아니면 들어가게 되는 for문의 범위가 3이 되어서 arr[i+k][j:j+3] = arr[k][:3]이 된다는 얘기. :3은 슬라이싱인데 0부터 할거라 0 생략한거라고 보면 된다. 그럼 여기서 i+k는 어떻게 될까?
위에서 9를 예시로 들었으니 9로 갑시다. 그러면
i, j = 0, 3, 6 k = 0, 1, 2(k는 div3, 즉 3까지) i+k = 0, 1, 2, 3, 4, 5, 6, 7, 8 j+div3 = 0, 6, 9
그러면 저 배열에서 호출하게 되는 위치가 잡힐것이다. 배열의 [k][:div3]은 [0][:3], [1][:3], [2][:3]이다.
어? 그럼 둘다 3이면? 위에서 i랑 j가 둘 다 0, 3, 6이라고 했는데 저기서 3,3이면 가운데라 뭘 채울 게 없다. (뇌피셜 주의)
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
이놈이랑 비슷하다. (저건 재귀함수로 계승 짠 거) 이제 문장 위치와 함수 위치가 중요하지…
n = int(input())
print('어느 한 컴퓨터공학과 학생이 유명한 교수님을 찾아가 물었다.')
def whatisrecursion(k):
print('재귀함수가 뭔가요?')
if k == 0:
print('"재귀함수는 자기 자신을 호출하는 함수라네"')
print('라고 답변하였지.')
return
print('"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.')
print('마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.')
print('그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어."')
whatisrecursion(k - 1)
print('라고 답변하였지.')
whatisrecursion(n)
아직 내지 맙시다. 언더바 남았어요.
어느 한 컴퓨터공학과 학생이 유명한 교수님을 찾아가 물었다.
"재귀함수가 뭔가요?"
"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.
마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.
그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어."
____"재귀함수가 뭔가요?"
____"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.
____마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.
____그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어."
________"재귀함수가 뭔가요?"
________"재귀함수는 자기 자신을 호출하는 함수라네"
________라고 답변하였지.
____라고 답변하였지.
라고 답변하였지.
이건 2에 대한 예시 출력인데, 언더바가 8개까지 붙어있는 게 있다. 함수를 총 세 번 호출하게 되고, 호출할때마다 언더바가 추가되는 식인데 4n꼴로 붙는다. 어? 그럼 그냥 k 곱하면 안되요? 그러면 밖에 있는 놈이 언더바가 제일 길어진다.
def whatisrecursion(k):
print('_' * 4 * (n - k) + '"재귀함수가 뭔가요?"')
if k == 0:
print('_' * 4 * (n - k) + '"재귀함수는 자기 자신을 호출하는 함수라네"')
print('_' * 4 * (n - k) + '라고 답변하였지.')
return
print('_' * 4 * (n - k) + '"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.')
print('_' * 4 * (n - k) + '마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.')
print('_' * 4 * (n - k) + '그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어."')
whatisrecursion(k - 1)
print('_' * 4 * (n - k) + '라고 답변하였지.')
n = int(input())
print('어느 한 컴퓨터공학과 학생이 유명한 교수님을 찾아가 물었다.')
whatisrecursion(n)
import sys
a,b,c=map(int,sys.stdin.readline().split())
while (a != 0 and b != 0 and c != 0):
if a ** 2 + b ** 2 == c ** 2:
print("right")
else:
print("wrong")
a,b,c=map(int,sys.stdin.readline().split())
그럼 이거 내면 되는 거 아니냐? 아뇨 내가 그거 냈다가 틀렸어요… 뭐야 왜 틀려요? 왜는 왜야… 저거 꼭 세번째로 입력하는 게 빗변일거라는 보장 있음? 그래서 입력받고 정렬을 한번 한 다음 들어가야 한다.
import sys
while True:
byeon = list(map(int,sys.stdin.readline().split()))
if sum(byeon) == 0:
break
byeon.sort()
if byeon[0] ** 2 + byeon[1] ** 2 == byeon[2] ** 2:
print("right")
else:
print("wrong")
파이썬 리스트는 리스트 개별 인덱싱을 통해 0번째 1번째 이런 식으로 끌고 와서 계산하는 게 가능하다. 그래서 입력받고 한번 정렬해 준 다음 로직을 들어가면 된다. 정렬을 해 주게 되면 빗변이 맨 마지막이그덩.
응용편-삼각형 판별하기
사실 피타고라스의 정리를 이용하면 예각삼각형인지 둔각삼각형인지도 알 수 있다. 위에서 a^2+b^2=c^2 면 직각삼각형이라고 했는데 둔각삼각형은 c^2가 a^2+b^2보다 크고 예각삼각형은 그 반대이기 때문.
두 원의 교점 개수를 구하는 문제. 참고로 문제에 나오는 터렛 이미지는 스1에 있는 미사일 터렛이다. (테란 건물임) 어떻게 알긴… 스타는 민속놀이 아님?
풀이
사실 이 문제는 두 원의 교점이 2, 1, 0, 무한대일 때에 대한 케이스를 로직으로 처리하면 되는 매우 개 심플한 문제다. 근데 케이스 여섯개임. 2, 1, 0, 무한대면 네 개 아니냐고? 1이랑 0이 케이스 두개씩 끼고 간다. 논리게이트의 X시리즈(XOR, XNOR)가 식 두개인거랑 비슷함.
그럼 각 케이스별로 알아보기 전에… 원의 교점 개수를 판별하기 위해서는 두 원의 중점간 거리와 반지름 정보가 필요하다. 그래서 입력이 XY좌표랑 반지름인 것. 그럼 어떻게 거리를 구하냐고? 저거 유클리드 거리라 구하는 거 쉽다.
여기다 대입하면 된다. 반지름은 r1+r2(합)와 |r1-r2|(차의 절대값) 두 개가 필요하다.
케이스 스터디
교점이 무한대: d = 0, r1 = r2
교점 없음: d > r1+r2 or d < |r1-r2|
교점이 하나: d = r1+r2 or d = |r1-r2| (앞에껀 외접 뒤에껀 내접)
교점이 둘: |r1-r2| < d < r1+r2
자 이제 IDE 켜자.
코드
import math
import sys
T = int(sys.stdin.readline())
for i in range(T):
x1,y1,r1,x2,y2,r2 = map(int,sys.stdin.readline().split())
d = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
sum_r = r2 + r1
min_r = abs(r1 - r2)
if d == 0 and r1 == r2:
print(-1)
elif d > sum_r:
print(0)
elif d < min_r:
print(0)
elif d == sum_r:
print(1)
elif d == min_r:
print(1)
else:
print(2)
sqrt()는 math 모듈이 필요하니 혹시 모듈 부르기 번거롭다면 0.5제곱 하자. (걍 루트=0.5제곱)
참고로 수학파트에 하나 남았는데 그거는 푸는 데 시간이 좀 오래 걸릴 것 같아서 일단 보류. 점심시간에 10~20분 남짓한 시간에 풀만한 문제가 아니었다 그건… 문제 읽다가 뇌에서 블루스크린 뜸…
풀이
재귀함수?
그… 이게 대충… 내가 라이츄 꺼내면 재귀함수임. 뭔소리여 그건
재귀함수는 정의단계에서 자신을 재참조하는 함수인데, 이따 풀이를 보면 알겠지만 함수 안에서 개 뜬금없이 함수가 또 호출되는 시추에이션이 벌어진다. 아 그래서 라이츄라고…그럼 상대가 꺼내면 뭔데요나 자신과의 싸움 참고로 모든 반복문과 변수로 짜여지는 알고리즘은 재귀함수로 표현이 가능하지만, 재귀함수를 쓰게 되면 흐름을 파악하기가 어렵다는 단점이 있다. 쌉고수들은 알지 않을까
코드! 코드를 보자!
def factorial(n):
if n == 1:
return 1
return n * factorial(n-1)
이게 예전에 재귀함수 공부하면서 짰던 팩토리얼 코드인데 저거 쌩으로 내면 틀려요…
저게 재귀함수의 형태이다. n이 1이면 1을 내놓고, 아니면 n에 n-1 함수 때려박은 걸 곱하라는 게 팩토리얼(n)에 대한 정의. 그럼 지금부터 저걸 쌩으로 내면 틀리는 이유를 알아보자.
첫째. 0!에 대한 정의가 안 되어 있다. (예시를 보면 10!과 0!이 있는데 저 코드는 1에서 끝나서 0 쓰면 depth 에러뜬다)
둘째. 입력과 출력이 없다. 함수만 딸랑 있고 저기에 넣을 숫자나 출력값에 대한 코드가 없다. return은 함수 돌리고 반환하라는거지 저거 자체로 화면에 출력하는 구문은 아니라서, 화면에 출력하려면 print문을 써야 한다.
import sys
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
N = int(sys.stdin.readline())
print(factorial(N))
그래서 입출력에 대한 구문이 들어가야 한다. 입력은 뭐 함수 위에 있든 밑에 있든 자유인데 본인 코딩 스타일이 모듈-함수(클래스)-입력-코드-출력 순서라…
소수점 로직은 손봐야 하는데, 공식은 저게 맞다. 유클리드 기하학에서 원의 넓이는 파이알제곱, 즉 반지름 제곱하고 파이(3.14) 곱하면 되지만 택시 기하학에서 원은 마름모꼴이기 때문에 마름모 넓이를 구하는 공식에 대입하면 된다. 근데 공식이 왜 저러냐고? 반지름이 주어지는거니까 거기에 곱하기 2 하면 마름모 대각선이 나온다.
편의상 인덱스(0,1,2)로 표기하자면, 0 = 1, 0 = 2, 1 = 2 세 가지 케이스에 대해 확인을 해야 한다. 그리고 저때에 대비해서 최소한 elif까지 포함해 분기가 네 개는 나와야 한다. (0이 1이나 2랑 같으면 0 곱하면 된다) 근데 리퍼런스에 답을 주신 분께서는 저걸 조건문 하나로 줄여버렸다.
입력값이 1 2 1일 때 리스트를 정렬하면 1 1 2가 되고, 입력값이 2 1 2일 때 리스트를 정렬하면 1 2 2가 된다. 즉, 정렬한 상태에서는 0 = 1 or 1 = 2이고, 이 때 공통분모가 1이니까 정렬한 리스트에서 두번째만 가져오면 된다.
import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
if m > 60:
h += 1
m -= 60
print('{} {}'.format(h,m))
이 문제의 조건문 분기 중 하나가 바로 분이 59보다 클 때에 대한 처리이다. 그럼 위 코드처럼 60 빼고 1 더하면 땡 아니냐고? 저거 저대로 내면 80분 90분 이렇게 더했을 때도 계산이 한 번만 된다. 조건문 자체는 뺑뺑이가 안 되기 때문. 다른 분들 풀이 보면 입력받은 분에 현재 시각의 분을 더해서 나누기 하시더라.
import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
while True:
m -= 60
h += 1
if m < 60:
break
print('{} {}'.format(h,m))
계산까지는 모르겠고 걍 와일트루 줘버림. 아 상여자는 반복문이라고 참고로 저거 시간초과는 아니지만 아무튼 틀렸으므로 아직 내지 말자.
시간이 23보다 클 때
import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
while True:
m -= 60
h += 1
if m < 60:
break
if h > 23:
h -= 23
print('{} {}'.format(h,m))
시간은 걍 빼면 되는데, 저거 틀린 코드니까 아무튼 아직 내지 말자.
뭐야 왜 틀려요?
시간초과 때문은 아니고… 저 로직에서 크게 잘못된 두 가지는 와일트루와 시간 계산쪽이다. 그럼 반례를 하나씩 보면서 얘기해보자.
while True의 반례
14 30
20
15 -10
뭐가 잘못됐는지 바로 이해가 되시리라 생각된다. 두시 30분에서 20분이 지나면 두시 50분이 되어야 하는데, 그냥 60 빼고 1 더하고를 한 것이다. While True를 쓸 거면 while문 내부를 저 순서대로 하면 안 된다.
while m > 59:
m -= 60
h += 1
그래서 while에 조건이 붙어야 한다. 저게 시간초과로 틀린 게 아니라는게 상당히 의외다
시간 계산 반례
시간계산 반례는 쉽다. 23시 59분에 1분 더했는데 0시 0분이 아니라 1시 0분이 나온다. 시간이 23보다 클 때 23을 빼게 되어 있는데, 저렇게 되면 24-23=1, 24시가 새벽 1시가 된다. 그래서 23보다 클 때 24를 빼면 된다.
import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
while m > 59:
m -= 60
h += 1
if h > 23:
h -= 24
print(h,m)
그래서 최종적으로 이 코드가 맞다. 아까 While True가 순서가 틀렸다고 했는데
import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
while True:
if m < 60:
break
m -= 60
h += 1
if h > 23:
h -= 24
print(h,m)
import sys
a = int(sys.stdin.readline())
print(a-543)
그냥 예시에서 입력-결과 해서 도출했음… ㅋㅋㅋㅋ input으로 하면 두 줄 가능합니다.
불기?
불멸기원으로, 보통 서기(달력에 있는 연도)에 600 혹은 599를 더하면 된다. 우리가 일반적으로 달력에서 쓰는, 그러니까 현재를 2022년으로 적는 그게 서기이고 예수의 탄생을 기준으로 한 것. 불기는 붓다의 입적이 기준이다. 그럼 여기서 질문. 단기는 뭐게요? 그렇다. 단기는 단군이 고조선을 세운 년도다.
단기는 서기에 2333년을 더한 값이다. 즉 올해는 단기로 4355년.
import sys
AD = int(sys.stdin.readline())
Buddha = AD + 600
Dangun = AD + 2333
print("입력하신 연도는 불기로 {0}년, 단기로 {1}년입니다. ".format(Buddha,Dangun))
4부터 50까지 골드바흐 추측을 만족하는 순서쌍이 이렇게 있는데, 잘 보면 쌍이 하나인 것도 있고 여러개인 것도 있다. 저 여러개인 것들 중, 소수간 차이가 제일 적은 것… 그러니까 맨 뒤에 있는 걸 출력하면 된다.
본편 풀이
import sys
T = int(sys.stdin.readline())
def isprime(a):
sqrt = int(a ** 0.5)
if a == 1:
return False
for i in range(2,sqrt+1):
if a % i == 0:
return False
else:
return True
prime = []
for i in range(4,10001):
if isprime(i):
prime.append(i)
이것도 범위가 있는게… 쌩으로 돌리면 응애 나 애기시간초과! 가 반길 것 같으니 리스트부터 만들어보자…
for i in range(T):
N = int(sys.stdin.readline())
for j in prime:
if j < N:
print(j)
그리고 이렇게 하면 일단 N보다 작은 소수가 다 나오긴 한다. 근데 우리가 출력하는 형식이 n m이잖아요?
for i in range(T):
N = int(sys.stdin.readline())
for j in prime:
if j < N and N - j in prime:
print(j,N-j)
근데 또 이렇게 하면 모든 순서쌍…이 중복으로 나온다. 8을 입력하면 3 5와 5 3이 나오는데 우리는 앞에 있는 수가 더 작은 순서쌍만 볼거임…
for i in range(T):
N = int(sys.stdin.readline())
for j in prime:
if j < N and N - j in prime and j < N - j:
print(j,N-j)
아, 저거 저렇게 하면 10이 5 5가 아니라 3 7만 나온다… 그리고 저 중에서 가장 차이가 작은 쌍을 출력하려면 또 뭘 어떻게 해야 하는거냐고…OTL
for i in range(T):
N = int(sys.stdin.readline())
a = N // 2
b = a
while a > 0:
if a in prime and b in prime:
print(a,b)
break
else:
a -= 1
b += 1
하던 찰나에 저걸 찾은 것이다.
예를 들어서 8을 입력했다 치면, a와 b는 4가 된다. 그런데 4는 소수가 아니기때문에 목록에 없다. 그러면 a는 1을 빼고, b는 1을 더한 다음 둘 다 소수인지 확인한다. 그리고 둘 다 소수면? Profit!
import sys
T = int(sys.stdin.readline())
def isprime(a):
sqrt = int(a ** 0.5)
if a == 1:
return False
for i in range(2,sqrt+1):
if a % i == 0:
return False
else:
return True
prime = []
for i in range(1,10001):
if isprime(i):
prime.append(i)
for i in range(T):
N = int(sys.stdin.readline())
a = N // 2
b = a
while a > 0:
if a in prime and b in prime:
print(a,b)
break
else:
a -= 1
b += 1
그래서 이렇게 내면 맞는다. 시간제한이 촉박하다 싶으면 반복문은 빼거나 최소한의 범위로만 할 수 있게 셋업해주는 게 좋을 듯 하다.
응용편-골드바흐의 약한 추측
역시 미쿡이야… 어지간한건 다 해봤어… 대단함…
import sys
def isprime(a):
sqrt = int(a ** 0.5)
if a == 1:
return False
for i in range(2,sqrt+1):
if a % i == 0:
return False
else:
return True
N = int(sys.stdin.readline())
for i in range(2,N + 1):
if isprime(i):
for j in range(i,N - i):
if isprime(N - i - j) and N - i + j == N:
print(i,j,N - i - j)
위에 함수파트는 똑같이 가면 된다. 아래쪽이… i가 소수고 i부터 N-i까지 중에서 N-i-j가 소수이고 N-i+j가 N이랑 같으면… 모르것다… 일단 출력 결과물을 보면서 얘기해보자.
9
2 2 5
3 3 3
9를 넣었을 때 어떻게 되는가?
i가 2부터 10까지인데(사실상 9) 2가 isprime을 돌려보니까 소수여
아따 그니까 j의 범위가 2에서 6까지(7 미만)인디
이 때 N-i-j는 9-2-2인 5다. 그리고 5가 isprime이고 N-i+j는 9-2+2니까 9다.
출(별)력. 이게 1차 루프다.
i가 3일때 3은 소수니까 isprime을 패스하고
j의 범위는 3부터 5까지(6 미만)인데
9-3-3이 3인디 3이 소수여… 그리고 9-3+3은 9여.
그래서 이렇게 된 거다. 252는 9-2+5가 9가 아니라 뺐나… 혹시 설명을 봐도 이해가 안되면…
def isprime(a):
sqrt = int(a ** 0.5)
if a < 1: # 실수로 0 200으로 입력했더니 0이 소수로 나와버림
return False
for i in range(2,sqrt+1):
if a % i == 0:
return False
else:
return True
일단 이놈은 소수파트 끝날때까지 가져가는 게 맞다.
import sys
def isprime(a):
sqrt = int(a ** 0.5)
if a < 1: # 실수로 0 200으로 입력했더니 0이 소수로 나와버림
return False
for i in range(2,sqrt+1):
if a % i == 0:
return False
else:
return True
while True:
P = []
N = int(sys.stdin.readline())
M = 2 * N
if N == 0:
break
for i in range(N+1,M+1):
if isprime(i):
P.append(i)
print(len(P))
일단 이렇게 해도 찾아는 준다. n부터 2n까지 isprime이라는 함수를 적용해서 소수면 리스트업하고, 최종 리스트 길이를 출력하는 건데… 이거 내면 뭐가 반기게요? 그렇죠… 응애 나 애기시간초과! 가 반겨요…
import sys
def isprime(a):
sqrt = int(a ** 0.5)
if a < 1: # 실수로 0 200으로 입력했더니 0이 소수로 나와버림
return False
for i in range(2,sqrt+1):
if a % i == 0:
return False
else:
return True
while True:
P = 0
N = int(sys.stdin.readline())
M = 2 * N
if N == 0:
break
for i in range(N+1,M+1):
if isprime(i):
P += 1
print(P)
이것도 응애 나 애기시간초과! 뜬다… 깝깝하잖아여? 아니 이러시는 이유가 있으실 것 아니세요… 그래서 질문을 찾아봤는데 리스트를 만들고 거기서 가져오라길래 뭔 소린가 했음… 그러다가 참고문헌을 발견했음.
import sys
def isprime(a):
sqrt = int(a ** 0.5)
if a == 1:
return False
for i in range(2,sqrt+1):
if a % i == 0:
return False
else:
return True
prime = []
for i in range(2,246912):
if isprime(i):
prime.append(i)
N = int(sys.stdin.readline())
while True:
P = 0
if N == 0:
break
for i in prime:
if N < i <= 2 * N:
P += 1
print(P)
N = int(sys.stdin.readline())
리스트를 만들고 가져오라는 건, n의 범위가 어쨌든 123456으로 정해져 있으니까 2n의 최댓값은 123456 * 2(246912)일거고, 그럼 거기까지 소수 리스트를 만들어 둔 다음 n을 입력받아서 n보다 크고 2n보다 작거나 같은 소수가 리스트에 있으면 세는 방식이라는 얘기. …다음 파트도 혹시 시간제한 있음?