프로그래머스 (고급) 친척 수

2024. 10. 8. 09:44·코딩 알고리즘 스터디


- 문제설명

친척 수란, 어떤 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
코딩마스터스 (중급) 밑장빼기  (2) 2024.10.01
프로그래머스 Lv2. 뒤에 있는 큰 수 찾기  (0) 2024.09.24
프로그래머스 Lv.1 소수 찾기  (0) 2024.09.19
'코딩 알고리즘 스터디' 카테고리의 다른 글
  • 프로그래머스 Lv2. 이모티콘 할인행사
  • 프로그래머스 Lv2. 타겟 넘버
  • 코딩마스터스 (중급) 밑장빼기
  • 프로그래머스 Lv2. 뒤에 있는 큰 수 찾기
Rabet
Rabet
  • 블로그 메뉴

    • 관리자
    • 글쓰기
  • Rabet
    卯
    Rabet
  • 전체
    오늘
    어제
    • Root (139)
      • KT AIVLE School (85)
        • Start (4)
        • Python프로그래밍 & 라이브러리 (6)
        • 데이터 처리 및 분석 (7)
        • 데이터 분석 및 의미 찾기 (7)
        • 웹크롤링 (10)
        • 머신러닝 (10)
        • 딥러닝 (6)
        • 시각지능 딥러닝 (10)
        • 언어지능 딥러닝 (6)
        • JAVA (4)
        • SQL (2)
        • 가상화 클라우드 (5)
        • 프로젝트 (8)
      • QA (2)
        • 오류사항 (1)
      • 웹공부 (14)
        • SPRING (11)
        • React (1)
      • 코딩 알고리즘 스터디 (23)
      • 코딩테스트 (9)
        • JAVA (8)
        • HTML (1)
      • CS공부 (3)
      • 자격증공부 (3)
        • 정보처리기사 (1)
        • 컴퓨터활용능력 1급 (1)
        • AICE Associate (1)
        • CSTS (0)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
Rabet
프로그래머스 (고급) 친척 수
상단으로

티스토리툴바