파이톨치

[BOJ][Pyhon][9184] 신나는 함수 실행 본문

알고리즘

[BOJ][Pyhon][9184] 신나는 함수 실행

파이톨치 2021. 8. 2. 22:48
728x90

[문제 및 출처]

https://www.acmicpc.net/problem/9184

 

9184번: 신나는 함수 실행

입력은 세 정수 a, b, c로 이루어져 있으며, 한 줄에 하나씩 주어진다. 입력의 마지막은 -1 -1 -1로 나타내며, 세 정수가 모두 -1인 경우는 입력의 마지막을 제외하면 없다.

www.acmicpc.net

[어떻게 풀까?]

w(1,1,1) -> w(0,1,1) + w(0,0,1) + w(0,1,0) - w(0,0,0)

나열을 해보면 이런식으로 된다.

w(2,2,2) -> w(1,2,2) + w(1,1,2) + w(1,2,1) - w(1,1,1)

이라? 나는 w(1,1,1)을 알고 있지 않나?

그렇다면 컴퓨터에게도 이것을 알려주면 좀더 쉽고 빠르게 하지 않을까?

반복은 컴퓨터가 훨씬 잘하니까 말이다. 그렇게 된다면 반복되는 구간은 확 줄어들 것이다.

코드를 구현해보면 다음과 같다. 

3차원 배열을 사용하는 아이디어는 여러 블로그에서 찾았다. 나머지 구현은 스스로 해보았다.

[코드]

#일단 구현해보고 짧게 만들 방법을 생각해보자.

def w(a, b, c):
    if a<=0 or b<=0 or c<=0:
        return 1
    if a>20 or b>20 or c>20:
        return w(20, 20, 20)
    if stack[a][b][c]:  #여기에 있어야 인덱스 에러 방지!
        return stack[a][b][c]
    if a<b and b<c:
        stack[a][b][c] = w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)
        return stack[a][b][c]
    
    stack[a][b][c] = w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)
    return stack[a][b][c]

stack = [[[0] * 21 for i in range(21)] for i in range(21)]

while True:
    a, b, c = map(int, input().split())

    if a==-1 and b==-1 and c==-1:
        break
    answer  = w(a, b, c)
    
    print(f"w({a}, {b}, {c}) = {answer}")

 

728x90

'알고리즘' 카테고리의 다른 글

[BOJ][Python] 2579번-계단 오르기  (0) 2021.08.07
[BOJ][Python][2580] 스도쿠 - 시간초과  (0) 2021.08.04
[BOJ][Python][9663] N-Queen  (0) 2021.08.01
[BOJ][Python][15651] N과 M(4)  (0) 2021.07.31
[BOJ][Python] [15651] N과 M(3)  (0) 2021.07.30