알고리즘/백준

BOJ) GCD 합 (9613 번)

Zin0_0 2021. 1. 26. 18:43
반응형

GCD 합

 

9613번: GCD 합

첫째 줄에 테스트 케이스의 개수 t (1 ≤ t ≤ 100)이 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있다. 각 테스트 케이스는 수의 개수 n (1 < n ≤ 100)가 주어지고, 다음에는 n개의 수가 주어진

www.acmicpc.net

GCD는 최대 공약수를 의미한다.

유클리드 호제법을 이용해서 쉽게 공약수를 구할 수 있다.

 

유클리드 호제법

위키에 따르면, 호제법이란 말은 두 수가 서로 상대 수를 나누어 원하는 수를 얻는 알고리즘 이라고 한다.

A와 B 라는 수가 있으면, A를 B로 나눈 나머지 A%B를 r이라고 한다. (단, A>B)

이 때, A와 B의 최대 공약수는 B와 r의 최대 공약수와 같다는 이론이다.

이 성질에 따라서, B를 r로 나눈 나머지 r'를 구하고, 다시 r을 r'로 나누는 과정을 반복하여 나머지가 0이 되었을 때 나누는 수(분모)가 A와 B의 최대 공약수가 된다.

 

1071과 1029의 최대공약수를 구하면,

  • 1071은 1029로 나누어떨어지지 않기 때문에, 1071을 1029로 나눈 나머지를 구한다. ≫ 42

  • 1029는 42로 나누어떨어지지 않기 때문에, 1029를 42로 나눈 나머지를 구한다. ≫ 21

  • 42는 21로 나누어떨어진다.

따라서, 최대공약수는 21이다.

 

 

간단하게 코드로 구현하면 아래와 같다.

public static int gcd(int p, int q)
 {
	if (q == 0) return p;
	return gcd(q, p%q);
 }

 

코드

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class SumGCD_9613 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();
        final String NEW_LINE = "\n";

        while(t-- >0) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken());
            int[] numArr = initNumArray(n, st);
            sb.append(solution(n, numArr)).append(NEW_LINE);
        }
        br.close();
        System.out.println(sb.toString());
    }

    private static int[] initNumArray(int n, StringTokenizer st) {
        int[] numArr = new int[n];
        for(int i=0; i<n; i++) {
            numArr[i] = Integer.parseInt(st.nextToken());
        }
        return numArr;
    }

    private static long solution(int n, int[] numArr) {
        long answer =0;
        for(int i=0; i<n; i++) {
            for(int j=i+1; j<n; j++) {
                answer += gcd(numArr[i], numArr[j]);
            }
        }
        return answer;
    }

    private static int gcd(int left, int right) {
        while(right !=0) {
            int target = left;
            left = right;
            right = target % right;
        }
        return left;
    }
}

 

반응형