[백준/Python] 1629번 곱셈

2025. 2. 20. 13:19·알고리즘문제풀이

문제

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


문제 이해

문제 이해는 간단했다.

a를 b번 거듭제곱 한 후, 그 수를 c로 나눈 나머지 값을 출력하면 되는 간단한 문제라 생각했다.

 

하지만 시간초과의 벽에 부딪혔다...


문제 풀이(시간초과 : pow)

# 시간초과(pow)
a, b, c = map(int, input().split())
ans = pow(a, b)
print(ans % c)

 

역시 실버는 실버인 이유가 있다.

이렇게 간단하게 풀릴 문제가 아니다.


문제 풀이(RecursionError : 재귀함수)

# 재귀함수(RecursionError)
a, b, c = map(int, input().split())
def power(x, y):
    if y == 1:
        return x
    return x * power(x, y-1)
print(power(a, b) % c)

 

시간초과를 해결하기 위해 재귀함수도 사용해봤지만 이것 역시 RecursionError가 발생했다.

RecursionError가 발생하는 이유는 재귀 호출이 너무 깊어져서 Python의 기본 재귀 제한을 초과했기 때문이다.

Python의 기본 재귀 제한은 약 1000번이므로 b의 값이 1000이상이라면 에러가 발생한다.


문제 풀이(정답 : 분할정복)

# 분할정복(정답)
# Time: 460 ms
a, b, c = map(int, input().split())

def divide(base, power, div):
    if power == 1:
        return base % div
    elif power % 2 == 0:
        temp = divide(base, power // 2, div)
        return (temp * temp) % div
    else:
        temp = divide(base, power // 2, div)
        return (temp * divide(base, power // 2 + 1, div) % div)

print(divide(a, b, c))

 

시간초과를 해결할 수 있는 방법 중 분할정복 이라는 개념을 알게되었다.

 

분할정복이란?

분할 정복 알고리즘은 그대로 해결할 수 없는 문제를 작은 문제로 분할하여 문제를 해결하는 방법이나 알고리즘이다.

 

이 문제에서는

${2^8} = {2^4} * 2^{4}$ 으로 분할하여 식을 표현할 수 있다.

 

그래서 나는 제곱이 1일 때, 짝수일 때, 홀수일 때의 경우를 나누어 코드를 작성했다.

  1. power가 1일 때
    간단한 경우이다. 그냥 base값을 div로 나눈 나머지 값을 리턴하면 끝이다.
  2. power가 짝수일 때
    ${2^8} = {2^4} * 2^{4}$ : 이 식처럼 코드를 작성한 후 나머지 값을 구하면 된다.
  3. power가 홀수일 때
    ${2^9} = {2^4} * 2^{4+1}$ : 이 식처럼 코드를 작성한 후 나머지 값을 구하면 된다.

이렇게 코드를 작성하니 정답을 구할 수 있었다.

하지만 이 코드보다 더 빠르게 구현할 수 있는 방법도 있었다!


문제 풀이(정답 : 분할정복 - 최적화)

# 분할정복(최적화)
# Time: 36 ms
a, b, c = map(int, input().split())

def divide(base, power, div):
    if power == 1:
        return base % div
    elif power % 2 == 0:
        temp = divide(base, power // 2, div)
        return (temp * temp) % div
    else:
        temp = divide(base, power // 2, div)
        return (temp * temp * base) % div

print(divide(a, b, c))

 

power가 홀수일 때의 코드를 재귀함수가 아닌 base를 한 번 곱해주는 것으로 수정했더니 훨씬 빠르게 코드가 실행되었다.

 

시간비교를 해보자면 처음 내가 풀었던 코드는 460ms였고 최적화 코드로 푼 속도는 36ms이다.

저작자표시 비영리 변경금지 (새창열림)

'알고리즘문제풀이' 카테고리의 다른 글

[백준/Python] 2606번 바이러스  (0) 2025.02.25
[백준/Python] 11659번 구간 합 구하기 4  (0) 2025.02.21
[백준/Python] 2178번 미로 탐색  (0) 2025.02.19
[백준/Python] 1697번 숨바꼭질  (0) 2025.02.18
[백준/Python] 1260번 DFS와 BFS  (0) 2025.02.17
'알고리즘문제풀이' 카테고리의 다른 글
  • [백준/Python] 2606번 바이러스
  • [백준/Python] 11659번 구간 합 구하기 4
  • [백준/Python] 2178번 미로 탐색
  • [백준/Python] 1697번 숨바꼭질
jungyn
jungyn
jungyn 님의 블로그 입니다.
  • jungyn
    jungyn 님의 블로그
    jungyn
  • 전체
    오늘
    어제
    • 분류 전체보기 (36)
      • 알고리즘문제풀이 (31)
      • 제로인턴 (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    DP
    18110
    제로인턴
    SYS
    BFS
    solved.ac
    counter
    카드1
    1629
    2차원행렬
    다이나믹프로그래밍
    스택
    1847
    프로그래머스
    후기
    시간초과
    11729
    교점개수
    2108
    2161
    2563
    스택 2
    너비우선탐색
    28278
    2606
    통계헉
    스택 수열
    백준
    사전직무교육
    수들의 합 2
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
jungyn
[백준/Python] 1629번 곱셈
상단으로

티스토리툴바