https://github.com/Dev-Guccin
Guccin
https://github.com/Dev-Guccin
전체 방문자
오늘
어제
  • 분류 전체보기 (172)
    • 알고리즘 (140)
    • 삽질방지 (13)
    • SystemHacking (1)
    • 일상 (4)
    • 개발 (8)
    • 스프링 부트 REST API 개발일지 (5)
    • JPA (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • DFS
  • 스택
  • 큐
  • 12015
  • heapq
  • DP
  • 유클리드호제법
  • 파이썬
  • MST
  • 프로그래머스
  • LIS
  • 백트래킹
  • python3
  • 유니온 파인드
  • counter
  • 그리디
  • 재귀
  • Python
  • 그래프
  • 최대공약수
  • 이분탐색
  • 최단경로
  • 다이나믹 프로그래밍
  • 이분 탐색
  • 백준
  • 다익스트라
  • 최소힙
  • 다이나믹프로그래밍
  • BFS
  • 재귀함수

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
https://github.com/Dev-Guccin

Guccin

[c++] 백준 1629 풀이 ( 곱셈, 분할 정복을 이용한 거듭제곱, long long )
알고리즘

[c++] 백준 1629 풀이 ( 곱셈, 분할 정복을 이용한 거듭제곱, long long )

2021. 8. 9. 13:47

이 문제는 예전에 파이썬으로 풀었던 적이 있다. 그러나 c++풀이는 또 다른 포인트가 있기때문에 다시 풀어보기로 했다.

일단 문제를 쓱 보자

 

문제를 보면 A를 B승하고 C로 나눈 나머지를 구하라는 뜻이다.
A,B,C 모두 21억을 넘는다. 이는 int의 최댓값 범위이다. 그렇다면 A^2일때 int를 넘어가서 오버플로우가 난다. 따라서 int보다는 long long을 사용하여 함수를 작성하는게 좋을 것 같다.

long long의 범위는 9,223,372,036,854,775,807 이다. 그런데 A는 21억이기 때문에 long long범위를 초과할 가능성도 있다고 생각했다. 21억에 붙은 0은 9개, long long 범위의 0개수는 18개이다. 즉, 연산중에 long long범위를 초과할 가능성이 존재하는 것이다. 따라서 중간중간 c로 나누어주어야 한다.

만약 B의 개수만큼 연산을 진행한다고 가정한다면 int범위인 21억번 계산을 해야한다. 따라서 분할정복을 이용하여 계산 횟수를 줄일 수 있다.
예를 들어 10^11이라면 10을 11번 곱해야한다.
그러나 연산의 값을 반 씩 나누어 구한다면 계산 횟수를 log11로 줄일 수 있다.(명확하게 맞는지는 잘 모르겠다. 그런데 시간이 확실히 줄어든다.) 
따라서 10^11을 구하기 전에 10^5를 구하고 10^5를 구하기 전에 10^2를 구하고 10^2를 구하기 전에 10^1을 구해서 필요한 곳에 사용만 해주면된다. 이에 대한 설명은 다른 곳에도 잘 나와있고 어렵지 않으니 넘어간다.

 

그럼 포인트는 아래와 같다.
1. 분할정복을 이용해 연산을 진행한다.
2. 오버플로우를 막기 위해 %c 를 중간마다 실행한다.

 

이를 토대로 코드를 작성한다. (pow함수를 사용하면 안된다. 왜냐하면 pow의 반환값이 int이므로 A*A를 하면 오버플로우가 일어나서 잘못된 값을 반환한다.)

#include<iostream>
using namespace std;
long long A, B, C;

long long divide(long long a, long long b, long long c) {
	if (b == 1) { // 탈출조건
		return a % c;
	}
	long long tmp = divide(a, b/2, c) % c;
	if( b % 2 == 0 ){//짝수면 구한거 바로 더하기
		return tmp * tmp % c;
	}
	else {//홀수면 나누고 a한번 더 곱
		return tmp * tmp % c * a % c;
	}
}
int main() {
	cin >> A >> B >> C;
	cout << divide(A, B, C);
}

 

저작자표시 (새창열림)

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

[python3] 백준 2293 풀이 ( 동전 1, 다이나믹 프로그래밍 )  (0) 2021.08.10
[python3] 백준 9465 풀이 ( 스티커, 다이나믹 프로그래밍, 이차원 배열 )  (0) 2021.08.09
[python3] 백준 2252 풀이 ( 줄세우기, 위상정렬, DAG, 그래프 )  (0) 2021.08.07
[c++] 백준 11657 풀이 ( 타임머신, 최단경로, 벨만-포드, 음수 가중치 )  (0) 2021.08.06
[python3] 백준 10844 풀이 ( 쉬운 계단 수, 다이나믹 프로그래밍, 이차 배열)  (0) 2021.08.05
    '알고리즘' 카테고리의 다른 글
    • [python3] 백준 2293 풀이 ( 동전 1, 다이나믹 프로그래밍 )
    • [python3] 백준 9465 풀이 ( 스티커, 다이나믹 프로그래밍, 이차원 배열 )
    • [python3] 백준 2252 풀이 ( 줄세우기, 위상정렬, DAG, 그래프 )
    • [c++] 백준 11657 풀이 ( 타임머신, 최단경로, 벨만-포드, 음수 가중치 )
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin

    티스토리툴바