일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 톰캐설치
- visual studio code 확장팩
- 파이썬
- 에디터 편리하게 사용
- 백준알고리즘 창문닫기
- 백준알고리즘
- 데이터베이스 오류
- 문자열비교
- JSP파일 생성
- slice
- korean language pack for visual studio code
- 웹프로젝트 생성
- the network adapter could not establish the connection
- 깃허브
- 자바
- 이클립스 설치
- 이클립스 연동
- Live Server
- comapreTo
- JDK설치
- Anaconda
- Dymanic Web Project
- 환경변수 설정
- github
- splice
- 백준알고리즘 13909
- 오라클 아마존 연동 오류
- vmware work station
- 이클립스
- face_recognition
- Today
- Total
물멍IT
[백준알고리즘] - 13909번 창문 닫기_Java 본문
백준 알고리즘 '약수, 배수와 소수2' 단계를 풀면서 최대 공약수, 최소 공배수 등
약수와 배수의 기초 수학적인 알고리즘을 많이 익혔다.
그러다가, 간단하게 보이는 제목의 '창문 닫기'에서 이전에 배웠던 약수와 배수 방식으로 문제를 풀다가 난관에 봉착했다.
문제를 처음 읽고 N=5인 경우를 가정해서 창문의 열고 닫힘의 경과를 풀었을 때
n의 약수의 개수가 홀수인 경우 n번째 창문이 열려있고,
n의 약수의 개수가 짝수인 경우 n번째 창문이 닫혀있다는 규칙을 찾아냈다.
1번 창문 | 2번 창문 | 3번 창문 | 4번 창문 | 5번 창문 | |
초기 상태 | 0 | 0 | 0 | 0 | 0 |
1번째 사람 | 1 | 1 | 1 | 1 | 1 |
2번째 사람 | 1 | 0 | 1 | 0 | 1 |
3번째 사람 | 1 | 0 | 0 | 0 | 1 |
4번째 사람 | 1 | 0 | 0 | 1 | 1 |
5번째 사람 | 1 | 0 | 0 | 1 | 0 |
1번 창문과 4번 창문의 특징은 약수의 개수가 홀수이다. (1=1, 4=1,2,4)
그러므로 처음에 작성한 코드는 약수의 개수를 세고 하고, 홀수인 경우만 카운트하도록 작성했다.
약수의 개수를 모두 셀 필요는 없고 제곱근까지만 세어 반복수행시간을 줄였다.
import java.util.*;
public class Main{
public static void main(String[] a) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int cnt = 0;
for(int i=1; i<=n; i++) {
if(getDivisorCnt(i)%2==1) {
cnt++;
}
}
System.out.println(cnt);
}
public static int getDivisorCnt(int num) {
int cnt = 1;
for(int i=1; i<=Math.sqrt(num); i++) {
if(num%i==0) cnt++;
}
return cnt;
}
}
결과는 시간초과였다.
내 코드에서 더이상 수행시간을 줄일 순 없다는 생각이 들어서 좀 더 쉬운 패턴을 찾아보았다.
그렇게 찾은 것이 약수의 개수가 홀수인 경우 약수에 제곱근이 포함된다는 것이었다.
n번 | 약수 | 제곱근 |
1 | 1 | 1 |
4 | 1, 2, 4 | 2 |
9 | 1, 3 | 3 |
16 | 1, 4 | 4 |
그렇게 다음에 생각한 것은 제곱근이 정수로 떨어지는 경우를 카운트 할려고 했다.
쉽게 조건문을 짠다면 [Math.sqrt(n) * 10 % 10 == 0] 요런식으로 말이다.
정답이라고 생각하고 다른 사람들 코드를 확인하였는데 웬걸... 반복문 없이 훨씬 간단하게 작성되어 있었다.
import java.util.*;
public class Main{
public static void main(String[] a) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println((int)Math.sqrt(n));
}
}
n번 제곱근의 정수형을 출력하는 형식으로 되어있기에 처음에는 이해가지 않았다.
어째서 제곱근을 가지는 정수를 카운트하지 않고도 n의 제곱근을 구하는 것으로 성립이 된다는 말인가 했다.
다른 블로그 글을 찾아봐도 n이하의 제곱근의 수 = n의 제곱근의 정수형 이라는 내용밖에 얻을 수 없었다.
그렇게 컴퓨터를 끄고 잠시 샤워를 하는 도중에 갑자기 이해가 되었다.
결국 제곱근이라는 것은 동일한 약수의 곱인것이다.
제곱근 | 제곱수 |
1 | 1 |
2 | 4 |
3 | 9 |
4 | 16 |
5 | 25 |
예를 들어, 10의 제곱근은 3.16227766017 이다. 그 이하의 정수형 제곱근 1, 2, 3이 존재한다는 것을 의미한다.
그렇기에 n의 제곱근의 정수형 = n이하의 제곱근 개수가 성립하는 것이다.
생각해보면 단순한 것을 나만 쉽게 이해하지 못한거 같았다.
다시한번 수학적 지식이 얼마나 코드를 쉽게 만들어주는지를 체감하면서...
오늘의 포스팅을 마친다.
'백준알고리즘문제' 카테고리의 다른 글
[백준알고리즘] - 10171번 고양이 출력하기_Java (0) | 2020.04.09 |
---|