Python Timeout

zzwwoonn·2022년 6월 1일
0

Algorithm

목록 보기
42/71

원본 코드

N, M, B = map(int, input().split())
inputMap = [list(map(int, input().split())) for i in range(N)]

answerTime = 10e9
answerHeight = 0

for height in range( 257 ):
    totalTime = 0
    block = B

    for i in range(N):
        for j in range(M):
            if height < inputMap[i][j]:
                totalTime += 2 * (inputMap[i][j] - height)
                block += (inputMap[i][j] - height)

            if height > inputMap[i][j]:
                totalTime += (height - inputMap[i][j])
                block -= (height - inputMap[i][j])
    
    if block < 0:
        continue
    
    if totalTime <= answerTime:
        answerTime = totalTime
        answerHeight = height
    
print(answerTime, answerHeight)

=> 시간 초과

if 비교 2번 -> if, else

N, M, B = map(int, input().split())
inputMap = [list(map(int, input().split())) for i in range(N)]

answerTime = 10e9
answerHeight = 0

for height in range( 257 ):
    totalTime = 0
    block = B

    for i in range(N):
        for j in range(M):
            if height < inputMap[i][j]:
                totalTime += 2 * (inputMap[i][j] - height)
                block += (inputMap[i][j] - height)

            else:
                totalTime += (height - inputMap[i][j])
                block -= (height - inputMap[i][j])
    
    if block < 0:
        continue
    
    if totalTime <= answerTime:
        answerTime = totalTime
        answerHeight = height
    
print(answerTime, answerHeight)

=> 시간 초과

check totalTime

totalTime 구하는 부분(시간이 얼마나 걸릴지 그 때마다 계산)을 2중 for 문을 다 돌고 나서 마지막에 한꺼번에 해주는 방식

N, M, B = map(int, input().split())
inputMap = [list(map(int, input().split())) for i in range(N)]

answerTime = 10e9
answerHeight = 0

for height in range( 257 ):
    minusVal = 0
    plusVal = 0

    for i in range(N):
        for j in range(M):
            if height < inputMap[i][j]:
                minusVal += (inputMap[i][j] - height)

            else:
                plusVal += (height - inputMap[i][j])
    
    if minusVal + B < plusVal:
        continue
    
    totalTime = 2 * minusVal + plusVal

    if totalTime <= answerTime:
        answerTime = totalTime
        answerHeight = height
    
print(answerTime, answerHeight)

=> 828 ms

change input

import sys

N, M, B = map(int, sys.stdin.readline().split())
inputMap = [list(map(int, sys.stdin.readline().split())) for i in range(N)]

answerTime = 10e9
answerHeight = 0

for height in range( 257 ):
    minusVal = 0
    plusVal = 0

    for i in range(N):
        for j in range(M):
            if height < inputMap[i][j]:
                minusVal += (inputMap[i][j] - height)

            else:
                plusVal += (height - inputMap[i][j])
    
    if minusVal + B < plusVal:
        continue
    
    totalTime = 2 * minusVal + plusVal

    if totalTime <= answerTime:
        answerTime = totalTime
        answerHeight = height
    
print(answerTime, answerHeight)

=> 828 ms

왜 차이가 없는지 모르겠으나 시간상으로 차이가 없다.. (그럼 굳이 왜 저걸 쓰라고 하는거지)

add comment

문제를 풀다가 필요한 내용들을 주석으로 적어놓는 경우가 많은데 이전에 경험에 비추어보면 주석도 시간을 재는데 영향이 조금 있는거 같더라

N, M, B = map(int, input().split())
inputMap = [list(map(int, input().split())) for i in range(N)]

answerTime = 10e9
answerHeight = 0

for height in range( 257 ):
    minusVal = 0
    plusVal = 0
    # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
    for i in range(N):
        for j in range(M):
            if height < inputMap[i][j]:
                minusVal += (inputMap[i][j] - height)
                # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
                # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
                # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
                
            else:
                # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
                # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
                plusVal += (height - inputMap[i][j])
    
    if minusVal + B < plusVal:
        # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
        # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
        # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
        continue
    
    totalTime = 2 * minusVal + plusVal

    # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
    # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
    # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ

    if totalTime <= answerTime:
        # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
        # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
        # ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ
        answerTime = totalTime
        answerHeight = height
    
print(answerTime, answerHeight)

=> 956ms

아슬아슬했다.

근데 또 똑같은 코드를 한번 더 제출하니까?

828ms가 나오더라. 이게 무슨...

같은 코드여도 제출 할 때마다 시간이 천차만별이다. 그럼 시간 재면서 시간 단축 시키려고 별 지ㄹ을 다 하는게 의미가 없잖아. 형평성이 안맞잖아. 시간이 짧다고 좋은 코드가 아닌게 되는거야? 같은 로직이여도 시간이 천차만별로 다르면 시간은 뭐 랜덤으로 찍히는거냐고

N-Queens 문제를 풀 때는 진짜 거진 1시간? 동안을 삽질했다. 포스팅 해놓은 글을 보면 알겠지만 if 조건문으로 걸러지지 않으면 바로 for문을 실행하는 코드였는데 for문 바로 위에 else를 해주지 않으니 시간 초과가 뜨더라. 도대체 이해가 안되더라. 그리고 더 어이없는 건 else를 적어주지 않고? 문제 풀면서 적어놓은 주석들을 지워줬더니 또 시간 초과가 안뜨고 맞췄습니다가 뜨더라.

use variable

import sys
N, M, B = map(int, sys.stdin.readline().split())
inputMap = [list(map(int, sys.stdin.readline().split())) for i in range(N)]

answerTime = 10e9
answerHeight = 0

for height in range( 257 ):
    # totalTime = 0
    minusVal = 0
    plusVal = 0

    for i in range(N):
        for j in range(M):
            if height < inputMap[i][j]:
                minusVal += (inputMap[i][j] - height)

            else:
                plusVal += (height - inputMap[i][j])
    
    inventory = minusVal + B
    if inventory < plusVal:
        continue

    time = 2 * minusVal + plusVal
    if time <= answerTime:
        answerTime = time
        answerHeight = height
    
print(answerTime, answerHeight)

minusVal + B 요 부분을 inventory 변수에 넣어서 if 조건문에 넣으니 816ms 가 나온다. 도대체 왜 ?

파이썬 엔진이 런타임에 코드를 해석할 때 변수를 선언해두고 쓰는 것과 그냥 값을 읽는거 중에 굳이 꼽자면 변수에 새로 넣고 그 변수를 쓰는 게 더 오래 걸려야 하는 게 아닌가?

.
.
.

혹시나 해서 다시 이전으로 돌려서 inventory 변수 안쓰고 그냥 돌려봤다.
=> 812ms

ㅋㅋ

1시간 동안 혼잣말로 중얼 중얼 대면서 가능한 모든 경우에 대해 테스트를 진행했지만 (소공을 너무 잘 배워서 그런 듯 ㅎ)

결론 : 시간에 큰 의미를 부여하지 말자 지 멋대로다.

대신 시간 초과는 피해야 문제를 맞출 수 있으니 의미있는 조건들만 다시 되새겨서 내걸로 만들자
(EX> if 2개 -> if else, 사실 이거 말고 다른 것들은 그닥.....)

0개의 댓글