- 문제설명
친척 수란, 어떤 N개의 수를 M으로 나누었을 때, 나머지가 모두 같게 되는 모든 M들을 말합니다. N개의 수가 주어졌을 때, 가능한 모든 친척 수를 알아내는 프로그램을 만드세요.
- 입출력 예
입력 #1
3
10
25
5
입력 #2
5
12
16
64
108
72
- 입력값 설명
첫째 줄에 종이에 적은 수의 개수 N이 자연수로 주어집니다. (2 ≤ N ≤ 30)
다음 줄부터 N개 줄에는 종이에 적은 수가 하나씩 주어집니다. 이 수는 모두 1보다 크거나 같고, 10,000보다 작거나 같은 자연수입니다. 같은 수가 두 번 이상 주어지지 않습니다. 항상 M이 하나 이상 존재하는 경우만 입력으로 주어집니다.
출력 #1
1 5
출력 #2
1 2 4
- 출력값 설명
첫째 줄에 가능한 M을 공백으로 구분하여 모두 출력합니다. 이때, M은 증가하는 순서이어야 합니다.
- 풀이 과정
나머지가 모두 같기 위해 최대공약수를 활용해야 겠다는 생각이 들었습니다.
수식으로 나타낸다면 아래와 같습니다.
최대 공약수는 어떤 두 개 이상의 자연수들이 있을 때, 두 수의 공통된 약수 중 가장 큰 수 입니다.
최대 공약수를 구하는 알고리즘에는 유클리드 알고리즘이 있습니다!
유클리드 알고리즘은 a와 b 두 수의 최대공약수는 b와 a%b의 최대공약수와 같다는 공식입니다.
이를 반복해가면서 두 정수를 작게 만들고 결국, a%b가 0이 되는 순간이 올 때 a의 값이 최대 공약수가 됩니다.
문제에서는 나머지를 같게하는 모든 M을 찾으라고 했으니 최대 공약수의 약수도 포함이 되기 때문에 마지막으로, 최대공약수의 약수를 찾으면 완성입니다. (0으로 완전히 나누어 떨어지는 수)
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int[] a = new int[N];
for (int i = 0; i < N; i++) {
a[i] = scanner.nextInt();
}
// 차이의 최대공약수 구하기
Arrays.sort(a);
int interval = Math.abs(a[1] - a[0]);
for (int i = 2; i < N; i++) {
interval = gcf(interval, Math.abs(a[i] - a[i - 1]));
}
ArrayList<Integer> list = new ArrayList<>(); // 정답
for (int i = 1; i <= interval; i++) { //최대공약수의 약수(즉 나누어 떨어지는 수 찾기)
if (interval % i == 0) {
list.add(i);
}
}
Collections.sort(list);
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
scanner.close();
}
public static int gcf(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
}
다른 스터디 부원분들께서는 약수를 구하는 부분에서 제곱근을 활용하여 푸는 방식을 활용하셨는데 이를 사용하면 더욱 빠르게 진행할 수 있었을 것 같았습니다.
for i in range(1, int(g**0.5) + 1): # 제곱근까지만 확인. 소수체크 체크 문제 풀 때 했던 기법.
if g % i == 0:
result.append(i)
if i != g // i: # i와 g//i가 다르면 둘 다 추가
모두 나누어 떨어지는 수를 찾는 다른 코드도 있었고 이렇게 좋은 코드도 있구나 생각이 들었습니다.
처음엔 min을 사용하셨지만 1,3,15를 넣어봤을 때 오류가 발생하였고 부원들과 논의를 해본 결과, max를 활용하여 오류를 해결하였습니다.
n = int(input())
L = []
for i in range(n):
L.append(int(input()))
max_num = max(L)
for i in range(1, max_num+1):
check = [x%i for x in L]
if check.count(check[0]) == len(check):
# print(check)
print(i, end =' ')
'코딩 알고리즘 스터디' 카테고리의 다른 글
프로그래머스 Lv2. 이모티콘 할인행사 (2) | 2024.10.21 |
---|---|
프로그래머스 Lv2. 타겟 넘버 (0) | 2024.10.14 |
코딩마스터스 (중급) 밑장빼기 (1) | 2024.10.01 |
프로그래머스 Lv2. 뒤에 있는 큰 수 찾기 (0) | 2024.09.24 |
프로그래머스 Lv.1 소수 찾기 (0) | 2024.09.19 |