베어_
TechBear
베어_
전체 방문자
오늘
어제
  • 분류 전체보기 (336)
    • Spring (33)
      • 개념 (13)
      • Security (5)
      • 실습 (1)
      • 토비 스프링 (11)
    • JPA (6)
    • 프로젝트 기록 (24)
    • DB (13)
    • JAVA (18)
    • 알고리즘 (50)
      • 유형정리 (8)
      • Baekjoon (21)
      • LeetCode (18)
    • 디자인패턴 (0)
    • 개발서적 (79)
      • Effective Java (78)
      • 객체지향의 사실과 오해 (1)
    • 독후감 (4)
    • 보안 (2)
    • 운영체제(OS) (53)
      • 공룡책 (53)
    • 컴퓨터 네트워크 (28)
      • 컴퓨터 네트워크 하향식 접근 (23)
    • 자료구조 (1)
    • DevOps (2)
    • 앱 개발 (20)
      • 안드로이드 스튜디오 (20)

블로그 메뉴

    공지사항

    인기 글

    태그

    • 운영체제
    • 자바8
    • 데이터베이스
    • 코드업
    • dfs
    • java
    • jpa
    • leetcode
    • 자바
    • 알고리즘
    • 스레드
    • 백준
    • 스프링시큐리티
    • 함수형인터페이스
    • Spring
    • 이펙티브자바
    • C++
    • 토비스프링
    • 스프링
    • BFS

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    베어_

    TechBear

    [백준] 1629 곱셈 (JAVA)
    알고리즘/Baekjoon

    [백준] 1629 곱셈 (JAVA)

    2022. 3. 12. 20:11

    ✉️문제

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

     

    1629번: 곱셈

    첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다.

    www.acmicpc.net

     

    📝 접근

    for문을 이용한 방법

    가장 간단한 방법이 for문을 이용하여 a를 b번 곱해주는 것이다. 

    for(int i = 0; i < b; i++) 
    	a *= b;

     

    하지만, 이 방법은 b가 50,000,000이 넘어가면 시간초과가 되어 버린다. (시간 제한 : 0.5).

    따라서, O(N)보다 빠른 알고리즘을 고려할 필요가 있다.

     

    분할 정복(Binary Search)

       분할 정복은 숫자의 1/2를 반복해서 구하는 것이다. 10^8을 분할 정복으로 구해보자.

    짝수 분할 정복

    먼저 왼쪽 그림에서 10^8이 10^4 두 개로 분할되는 것을 확인할 수 있다. 여기서 중요한 것은 일단 10^4의 값을 구하면 자기 자신을 한 번 더 곱함으로써 10^8의 값을 구할 수 있기 때문에 왼쪽으로 뻗어나가는 가지의 값만 구하면 이를 가볍게 해결 할 수 있다. 이 분할 정복을 이용하면 시간 복잡도가 O(log N)으로 줄어든다. 

     -> 10^4, 10^2, 10^1 값만 알면 10^8을 구할 수 있다.

     

    그렇다면 홀 수의 경우는 어떻게 분할 정복을 해야 할까? 10^5를 분할 정복해보자.

    홀수의 경우 밑을 한 번 더 곱해주면 된다.

    홀 수 분할 정복

    이를 코드로 표현해보자.

    static long pow(long base, long exponent) {
    
        // 밑, 지수 = 1
        if(exponent == 1 || base == 1) 
        	return base;
        
        // 분할
        long tmp = pow(base, exponent / 2);
        
        // 홀 수
        if(exponent % 2 == 1)
        	return tmp * tmp * base;
            
        // 짝 수
        return tmp * tmp;
    }

     

    모듈러 연산

    문제를 다시 한 번 확인해보자. 입력 값의 범위가 int의 MAX값 까지 주어질 수 있기 때문에 c로 나눈 나머지를 계산하도록 되어 있다. 이를 위해 모듈러 연산이 필요하다. 공식은 다음과 같다.

    모듈러 합동 공식

    이를 코드로 표현해보면 다음과 같다.

        static long pow(long base, long exponent) {
            if(base == 1 || exponent == 1)
                return base % c;
    
            long tmp = pow(base, exponent / 2);
    
            if(exponent % 2 == 1)
                return (tmp * tmp % c) * base % c;
    
            return tmp * tmp % c;
        }

     

    🗝 문제풀이

    import java.util.Scanner;
    
    public class B1629 {
    
        static int a, b, c;
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
    
            a = sc.nextInt();
            b = sc.nextInt();
            c = sc.nextInt();
    
            System.out.println(pow(a, b));
        }
    
        static long pow(long base, long exponent) {
            if(base == 1 || exponent == 1)
                return base % c;
    
            long tmp = pow(base, exponent / 2);
    
            if(exponent % 2 == 1)
                return (tmp * tmp % c) * base % c;
    
            return tmp * tmp % c;
        }
    }

     

     

    다음 블로그를 참고하여 작성하였습니다.

    https://st-lab.tistory.com/237

      '알고리즘/Baekjoon' 카테고리의 다른 글
      • [백준] 7576 토마토 (JAVA)
      • [백준] 2606 바이러스(JAVA)
      • [백준] 10830 행렬 제곱 (JAVA)
      • [Baekjoon] 12865 평범한 배낭 문제
      베어_
      베어_
      Today I learned | 문제를 해결하는 개발자

      티스토리툴바