문제
양수 A가 N의 진짜 약수가 되려면, N이 A의 배수이고, A가 1과 N이 아니어야 한다.
어떤 수 N의 진짜 약수가 모두 주어질 때, N을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N의 진짜 약수의 개수가 주어진다. 이 개수는 50보다 작거나 같은 자연수이다.
둘째 줄에는 N의 진짜 약수가 주어진다. 1,000,000보다 작거나 같고,
2보다 크거나 같은 자연수이고, 중복되지 않는다.
출력
첫째 줄에 N을 출력한다. N은 항상 32비트 부호있는 정수로 표현할 수 있다..
타입 | 범위 | bit | byte |
---|---|---|---|
byte | -128 ~ 127 | 8 | 1 |
short | –32,768 ~ 32,767 | 16 | 2 |
int | –2,147,483,648 ~ 2,147,483,647 | 32 | 4 |
long | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | 64 | 8 |
알아야하는 것은 수학의 약수이다.
나는 수학 개념을 전부 잊어버려서 초등 수학 블로그를 보면서 다시 개념을 숙지했다. 😂
약수 개념을 알고있는 사람이라면 문제없이 풀 수 있는 문제 같다.
N을 구하기 위해서는 약수의 성질을 이용하면 된다.
EX)
예를 들어 N이 20이라면
약수는 1, 2, 4, 5, 10, 20
이 된다.
그 중 1과 자기 자신을 제외한 진짜 약수는
2, 4, 5, 10
이다.
즉, 진짜 약수의 최댓값과 최솟값을 곱하면 N을 구할 수 있다.
import java.util.Scanner;
public class jun_1037 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int divCount = sc.nextInt();
int[] divArray = new int[divCount];
for (int i = 0; i < divCount; i++) {
divArray[i] = sc.nextInt();
}
Arrays.sort(divArray); // 정렬
int divMin = divArray[0];
int divMax = divArray[divCount - 1];
System.out.println(divMin * divMax);
}
}
import java.util.Scanner;
public class jun_1037 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int divCount = sc.nextInt();
int divMax = Integer.MIN_VALUE;
int divMin = Integer.MAX_VALUE;
while (divCount-- > 0) {
int tmp = sc.nextInt();
divMax = tmp > divMax? tmp : divMax;
divMin = tmp < divMin ? tmp : divMin;
}
System.out.println(divMax * divMin);
}
}
// 이건 다른 사람 풀이를 보고 솔직히 신기해서 따라 풀어봤다.
// 나는 배열을 사용하는 방법만 생각했는데 이런 발상이 가능하다니..
public class jun_1037_bufferdReader {
public static void main(String[] args) throws IOException { // 입출력 예외 처리
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); // 콘솔에서 입력값을 입력받을 BufferedReader 객체 생성
int divCount = Integer.parseInt(bf.readLine()); // BufferedReader.readLine()은 한 줄의 문자열을 읽어오고 String을 리턴한다.
int[] divArray = new int[divCount];
// 입력 문자열을 공백으로 구분하기 위한 StringTokenizer 추가
StringTokenizer st = new StringTokenizer(bf.readLine(), " "); //readLine()으로 읽어들인 문자열을 공백 구분자를 기준으로 분리
for (int i = 0; i < divCount; i++) {
divArray[i] = Integer.parseInt(st.nextToken()); // StringTokenizer.nextToken() 다음 토큰을 String으로 반환
}
Arrays.sort(divArray); // 정렬
int divMin = divArray[0];
int divMax = divArray[divCount - 1];
System.out.println(divMin * divMax);
}
}
public class jun_1037_bufferdeReader2 {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int divCount = Integer.parseInt(bf.readLine());
int divMax = Integer.MIN_VALUE;
int divMin = Integer.MAX_VALUE;
StringTokenizer st = new StringTokenizer(bf.readLine(), " ");
while (divCount-- > 0) {
int tmp = Integer.parseInt(st.nextToken()); // divCount번만큼 반복
divMax = tmp > divMax ? tmp : divMax;
divMin = tmp < divMin ? tmp : divMin;
}
System.out.println(divMax * divMin);
}
}
코드3
과 코드4
for문
divCount
회 반복 코드4
도 마찬가지로 while문 하나만 존재 -> 1*nArrays.sort()
내부적으로 DualPivotQuicksort 정렬을 사용한다.
Quicksort 정렬 알고리즘은 평균적으로 가장 빠른 정렬 알고리즘
Primitive 타입 배열을 입력했을 때 평균 시간복잡도는 O(nlogn), 최악의 경우는 O(n^2)
Java에서 사용하고 있는 dual-pivot quicksort는 O(N^2)의 시간 복잡도로 동작할 일은 사실상 없을 수준으로 개선했기 때문에 실무에서 사용하는 데에 문제가 없지만, 그럼에도 불구하고 시간복잡도를 O(N^2)으로 만드는 데이터를 생성하는 것이 가능은 함
그러므로 정렬 알고리즘 문제와 같이 시간 복잡도 O(NlogN)을 보장하는 정렬 코드를 작성해야 한다면 기본형(Primitive) 타입의 배열을 Arrays.sort()로 정렬하는 것은 무리무리
시간 복잡도 면에서는 정렬 시 Arrays.sort()보다 collections.sort가 더 유리한 면이 많다. 이 문제에서는 괜찮았지만 정렬할 값이 많아지면 collections.sort를 쓰자.
코드3
의 시간복잡도는 1*n + n^2 = O(N^2)
코드4
의 시간복잡도는 1*n = O(n)
Quicksort 알고리즘의 공간복잡도
내가 보려고 정리하는 개념
- 약수: 어떤 수를 나누어 떨어지게 하는 수
- Integer.MIN_VALUE : integer의 최솟값을 제공하는 상수
- Integer.MAX_VALUE : integer의 최댓값을 제공하는 상수
- Arrays.sort()는 static메서드이므로 인스턴스를 생성하지 않고 바로 사용할 수 있다.
출처: https://codingnojam.tistory.com/38
더 알아보고 싶은 것
- split과 StringTokenizer 비교
- 코딩테스트 입력에 사용되는 메소드
참고자료 : 3sammy님의 코딩테스트 입력 구분
참고자료2 : iseunghan 님의 [Java] BufferedReader, BufferedWriter로 빠른 입출력 하기- JAVA [자바] - 입력 뜯어보기 [Scanner, InputStream, BufferedReader]
Rf
- frost00 님의 [Java] 정수형(byte, short, int, long) 정리
- ST_ 님의 [백준] 1037번 : 약수 - JAVA [자바]
- 코메인 님의 [백준/BOJ] 1037번 : 약수 (JAVA / 자바)
- 양햄찌 님의 자바 입출력 함수 BufferedReader
- 양햄찌 님의 StringTokenizer 클래스로 문자열 분리하기
- 알면 know jam! 모르면 no jam!:티스토리
- djm03178 님의 특별한 정렬 알고리즘들 2
- 클로키 님의 자바 bufferedreader & writer 사용법과 IOException (백준 15552번)