반응형
1. 문제 번호 1978번
2. 문제 풀이
한줄 평가
- 특히나 배열의 index는 너무 헷갈리게 한다.
- 처음에 잘못 설계한 탓에 2시간 넘게 ..걸렸다.
- 입력받은 1 3 5 7을 7까지 true,false로 초판 초기화하여 진행하려다가 맨 마지막에 잘못됨을 깨달았다.
- continue는 아래를 실행하는게 아니라 for문을 다시 실행 (당연하지만 실수를 했다.)
문제를 먼저 정확히 파악
나의 문제풀이 방식 및 순서
* 나의 다양한 학습이 우선이기 때문에 다양한 방법을 생각 *
2시간 짜리 헛고생을 지독하게 했다.
- 1 3 5 7 을 배열 index 1 ~4까지 넣었다. ( ..?? 왜 그랬지.. 0에 다가 안넣으려고 별 짓을 다했다.)
- 7까지 8자리 인덱스 배열에 boolean으로 다 만들었다.
- 에라토스테네스 체를 사용
- 남은것을 출력 ( 2 3 5 7 이 출력되버림..ㅡㅡ 2는 입력을 받지 않았으니 출력되면 안됐었다..)
3. 소스 인증
import java.util.*;
import java.lang.*;
import java.io.*;
// The main method must be in a class named "Main".
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int isPrimeCnt = 0;
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i = 0; i < N; i++){
boolean isPrimeYn = false;
isPrimeYn = isPrime(Integer.parseInt(st.nextToken()));
if(isPrimeYn) {
isPrimeCnt++;
}
}
System.out.println(isPrimeCnt);
}
public static boolean isPrime(int inputNum){
if(inputNum < 2) return false;
int end = (int)Math.sqrt(inputNum);
for(int i = 2; i <= end; i++){
if( (inputNum % i) == 0) {
return false;
}
}
return true;
}
}
import java.util.*;
import java.lang.*;
import java.io.*;
/*
이 방법은 쓰지마세요 ㅋㅋㅋ
나의 문제풀이 방식 및 순서 보시면 잘못된 설계가 결과도 이상하게 만듭니다..
*/
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int inputCnt = Integer.parseInt(br.readLine());
int [] inputAry = new int[inputCnt];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i = 0; i < inputCnt; i++) {
inputAry[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(inputAry);
primeNumberSieve(inputAry);
}
static void primeNumberSieve(int[] inputAry){
// int maxValue = inputAry[inputAry.length-1];
int maxValue = Arrays.stream(inputAry).max().getAsInt();
boolean[] isPrime = new boolean[maxValue+1];
Arrays.fill(isPrime,true); //모두 소수로 초기화
isPrime[0] = isPrime[1] = false;
/*에라토스테네스 체 사용*/
for(int i = 2; i <= Math.sqrt(maxValue); i++){
if(isPrime[i]){ //continue; //이미 지워진 숫자는 무시
for(int j = i*i; j <= maxValue; j += i){ //배수는 삭제
isPrime[j] = false;
}
}
}
int countPrimeNumber = 0;
// for(int i = 0; i < isPrime.length; i++){
// if(isPrime[i]){
// countPrimeNumber++;
// }
// }
for(int num : inputAry) {
if(isPrime[num]) {
countPrimeNumber++;
}
}
System.out.print(countPrimeNumber);
}
}
- 실패 소스코드 -
4.추가 개념
에라토스테네스의 체
- 개념 : 여러개의 소수를 한 꺼번에 판별하고자 할 때 사용
import java.util.*;
import java.lang.*;
import java.io.*;
class Main {
public static void main(String[] args) {
System.out.println(isPrimeNumber(57));
}
static boolean isPrimeNumber(int i){
for(int j = 2; j < i; j++){
if( i % j == 0 ) return false;
}
return true;
}
}
소수를 판별하기 위해 제일 간단하게 생각할 수 있는 소수 판별 알고리즘이다. 다만 for문을 2부터 n-1까지 모두 순차적으로 돌아야 하기 때문에 O(N)의 시간 복잡도를 가져 비효율 적이다. (앞선 알고리즘을 전부다 이렇게 풀었기 때문에 이제는 동영상 강의를 들어야 할 것 같다고 생각이 듬)
사실은 \(O(N\tfrac{1}{2})\)로 해결할 수 있다.
소수는 1,2,3,5,7,11 과 같이 "1과 자기 자신 외의 약수를 가지지 않는 1보다 큰 자연수' 이다.
모든 약수는 대칭형태이다.
예를 들어 A가 12 일 때 A = 2×6, 3×4, 4×3, 6×2인데 √12 = 3.46 정도가 되므로 2~3까지만 확인 해보면 된다.
아래와 같이 참조하여 \(O(N\tfrac{1}{2})\) 로 계산이 가능하다.
import java.util.*;
import java.lang.*;
import java.io.*;
class Main {
public static void main(String[] args) {
System.out.println(isPrimeNumber(97));
}
static boolean isPrimeNumber(int i){
int end = (int)Math.sqrt(i);
for(int j = 2; j <= end; j++){
if( i % j == 0 ) return false;
}
return true;
}
}
그렇다면 왜 에라토스테네스의 체를 배우는가?
이유는 여러 개의 소수를 한꺼번에 판별하고자 할때 사용하기 위해서 사용한다.
- 시작부터 끝까지 배열을 만든다. (2~N까지)
- 먼저 2의 배수를 지우며 본인은 Skip한다.
- 3의 배수를 지우며 본인은 Skip한다.
- 5의 배수를 지우며 보인은 Skip한다. (이미 4는 지웠기 때문에 건너뛴다.)
5. 참조 블로그
불편함을 느끼실 경우 연락 주시면 곧 바로 삭제하도록 하겠습니다.
728x90
반응형
'알고리즘(BOJ) 문제풀이' 카테고리의 다른 글
[BOJ/백준] 약수, 배수와 소수_ 11653번 (2) | 2024.06.03 |
---|---|
[BOJ/백준] 약수, 배수와 소수_ 2581번 (0) | 2024.06.02 |
[BOJ/백준] 약수, 배수와 소수_ 9506번 (0) | 2024.06.01 |
[BOJ/백준] 약수, 배수와 소수_ 2501번 (0) | 2024.06.01 |
[BOJ/백준] 약수, 배수와 소수_ 5086번 (0) | 2024.05.31 |