문제 링크 / level: Bronze IV
https://www.acmicpc.net/problem/2753
내가 생각한 풀이
윤년에 대한 로직을 공부하기 위해 풀어봤다.
예전에 분명 풀어봤던 기억이 있어서 SWEA 사이트에서 뒤지다가 안 나오길래 BOJ 뒤지니까 바로 나옴^_^ㅎㅎ
아무튼 윤년을 구하는 로직은 이러하다고 한다.
1. 4의 배수이면서 100의 배수가 아닐 때
2. 4의 배수이면서 400의 배수일 때
이게 무슨 소리인지 헷갈리는 부분이 있기 때문에 잘 생각해봐야한다.
일단, 윤년의 조건을 만족하려면 4의 배수여야한다는 것은 확실하다. 그런데 그 다음이 문제다.
4의 배수이면서
100의 배수면 윤년이 아닌데,
400의 배수면 윤년이다?
// 핵심 코드
if(year%4==0) { // 4의 배수이면서
result = true;
if(year%100==0) {result=false;} // 100의 배수가 아닐 때 윤년 (즉, 100의 배수면 윤년 X)
if(year%400==0) {result=true;} // 400의 배수면 윤년
}
코드로는 이렇게 표현할 수 있다. 그냥 문제에 적혀있는 그대로, 시키는 대로 코드를 짜면 문제는 쉽게 맞힐 수 있다.
하지만 나는 이에 그치지 않고 정확한 논리를 이해해보기로 했다.
4의 배수: 4, 8, 12, 16, 20, 24, 30...
100의 배수: 100, 200, 300, 400, 500, 600, 700, 800...
400의 배수: 400, 800, 1200, 1600, 2000...
'4의 배수이면서 100의 배수가 아닐 때'라는 것의 의미는 4의 배수 중에서 동시에 100의 배수인 것들을 제외시키라는 의미겠다. 집합의 개념을 활용하자면 차집합 개념이 사용되는 것으로 볼 수 있을 것 같다. (예: A-B)
그리고 '4의 배수이면서 400의 배수일 때'라는 것의 의미는 4의 배수 중에서 100의 배수인 것들을 제외한다. 그리고 제외될 위기에 처한 녀석들 중에서 400의 배수면 윤년이므로 이를 확인하고 조건을 통과하면 다시 살려준다.
집합을 통해 이를 표현하자면 4의 배수 중에서 100의 배수인 것을 제외하므로 A-B와 같이 표현할 수 있고, 여기에 4의 배수이면서 400의 배수인 것들의 모임이라고 생각하자면 A-B인 상태에서 C를 더해주는 것으로 볼 수 있을 것이다. (A-B+C와 같은 형태)
이제 내가 위에서 작성한 코드를 뜯어보자.
boolean형 변수인 result는 false로 초기화해준다. (윤년이면 true, 윤년이 아니면 false)
if(year%4==0) { --> 윤년이 되려면 기본적으로 4의 배수여야 하므로 이 조건을 가장 바깥에 둔다.
result = true; --> 일단 윤년이라고 치고~
if(year%100==0) {result=false;} --> 4의 배수이면서 100의 배수일 경우에는 윤년이 아니므로 false
(100의 배수를 거르기 위해 조건문을 '100의 배수일 때'로 두었다.)
if(year%400==0) {result=true;} --> 걸러진 애들 중에서 400의 배수가 있다면 윤년이 맞으므로 true
result = true;를 이 곳에 두면 위의 if문에서 false로 걸러진 애들이 다시 true가 되므로
일단 처음에 윤년이라고 치고, 조건문을 통해 윤년이 아닌 애들을 걸러내는 작업을 해주는 방식이다.
}
year가 4의 배수가 아닌 경우, 바로 이쪽으로 넘어오며 result의 값은 false다. (초기값)
스스로도 제대로 납득이 될 수 있도록 (그리고 나중에 또 헷갈리지 않도록) 일부러 구구절절 해설을 적어봤다.
중요 포인트는 2개 정도가 있다.
1. if(year%100==0)와 if(year%400==0)의 순서가 중요하다.
왜냐하면 일단 4의 배수인 애들 중에서 색출을 하는 과정인데, 동시에 100의 배수인 애들을 거르는 과정이 먼저다. 그리고 그 이후에 400의 배수인 애들이 있다면 true로 업데이트 해준다. 이 논리에 맞게 순서를 지켜줘야 한다.
2. 만약 if(year%400==0)라는 조건이 없다면 100의 배수 중에서 400의 배수인 애들도 걸러진 것이므로 프로그램이 제대로 작동하지 않는다. 착각하지 않도록 주의할 것. 100의 배수이지만 400의 배수라면 다시 구제해주는 과정이 반드시 필요하다.
▼아래 더보기를 누르면 코드 전체를 볼 수 있습니다.
[코드 보기]
마지막에 결과 출력할 때도 삼항연산자로 깔끔하게 마무리해줬다.
사실 알고리즘 문제를 풀기 전까지는 삼항연산자를 그렇게 자주 사용하지는 않았던 것 같은데, 알고리즘을 풀다보면 결과 출력하거나 값을 업데이트 해줄 때 종종 요긴하게 사용하게 된다^_^ 그러면 왠지 고수가 된 느낌임. 꿀잼~🍯😊
'🥇Problem Solving (psS2mj) > BOJ' 카테고리의 다른 글
[BOJ] 2748. 피보나치 수 2 (Java) (0) | 2020.04.07 |
---|---|
[BOJ] 2747. 피보나치 수 (Java) (0) | 2020.04.07 |
[BOJ] 16430. 제리와 톰 (Java) (0) | 2020.04.06 |
[BOJ] 7576. 토마토 (Java) (0) | 2020.03.30 |
연습 - [BOJ] 7576. 토마토 (Java) (0) | 2020.03.29 |
댓글