BOJ | 2753번

송치헌·2021년 5월 27일
0
post-thumbnail
post-custom-banner

Python 풀이

A = int(input())

if A%4==0: # 4로 나누어 떨어질 때 (4의 배수일 때)
    if A%400==0: # 400으로 나누어 떨어지면 (4의 배수이면서 400의 배수이면)
        print(1) # 윤년
    elif A%100==0: # 100으로 나누어 떨어지면 (4의 배수이면서 100의 배수이면)
        print(0) # 윤년 아님
    else: # 4의 배수이지만 400으로 나누어 떨어지지 않고 100으로 나누어 떨어지지 않으면 (4의 배수이지만 100의 배수와 400의 배수가 아니면)
        print(1) # 윤년
else: # 4의 배수가 아니면
    print(0) # 윤년 아님

연도를 입력받아서 4의 배수이면서 100의 배수가 아니면 윤년, 또는 400의 배수이면 1을 출력하고 아니라면 0을 출력하는 문제이다.

경우의 수를 나눠보면

  • 4의 배수
    • 100의 배수
      • 400의 배수 : 윤년 (1출력)
      • 400의 배수가 아님 : 윤년이 아님 (0출력)
    • 100의 배수가 아님 : 윤년 (1출력)
  • 4의 배수가 아님 : 윤년이 아님 (0출력)

4의 배수이면서 100의 배수이면서 400의 배수 : 윤년
4의 배수이면서 100의 배수이면서 400의 배수가 아님 : 윤년이 아님
4의 배수이면서 100의 배수가 아님 : 윤년
4의 배수가 아님 : 윤년이 아님

4의 배수인가100의 배수인가400의 배수인가윤년인가
4의 배수 [O]100의 배수 [O]400의 배수 [O]윤년 [O]
400의 배수 [X]윤년 [X]
100의 배수 [X]윤년 [O]
4의 배수 [X]윤년 [X]

이 표대로 코딩해주면 된다.

4의 배수이면:
	100의 배수이면:
    		400의 배수이면 : 윤년 O
            	400의 배수가 아니면 : 윤년 X
    	100의 배수가 아니면 : 윤년 O
4의 배수가 아니면 : 윤년 X

C++ 풀이

#include <iostream>

using namespace std;

int main()
{
	int year;
	cin >> year;
	((!(year % 4)) && (year % 100)) || (!(year % 400)) ? cout << 1 : cout << 0;
}

C++은 삼항 연산자를 이용하여 풀이하였다. 삼항 연산자를 쓰는게 더 편한 것 같다.
A operator B ? true : false A와 B의 연산 결과가 참이면 첫번째 항, 거짓이면 두번째 항이 실행된다. 예를 들어보자.

#include <iostream>

int main(){

  int a = 3;
  int b = 5;

  a < b ? std::cout << "a가 b보다 작습니다." : std::cout << "a가 b보다 큽니다.";
  
}

a가 b보다 작기 때문에 a < b의 값은 true가 되어서 왼쪽에 있는 a가 b보다 작습니다.가 실행된다.

조건을 3개 이상일 경우 삼항 연산자 안에 또 삼항 연산자를 넣어서 작성할 수 있지만 그럴 경우 if문으로 구현하는게 더 효율적이라고 생각한다.

문제로 돌아가서 ((!(year % 4)) && (year % 100)) || (!(year % 400)) ? cout << 1 : cout << 0; 이 부분만 분석을 해보자면
(year % 4) 는 연도를 4로 나눈 나머지인데 그 값이 0이면 false 0이 아니면 true 가 반환된다. 근데 !(year % 4) 앞에 !가 붙어있기 때문에 결과값을 부정한다. 즉, true이면 false로, false이면 true로 바꿔준다.

위의 표를 잠깐 다시 가져와서 보면

4의 배수인가100의 배수인가400의 배수인가윤년인가
4의 배수 [O]100의 배수 [O]400의 배수 [O]윤년 [O]
400의 배수 [X]윤년 [X]
100의 배수 [X]윤년 [O]
4의 배수 [X]윤년 [X]

4가지 경우를 위에 있는 코드에 대입해 보자.

((!(year % 4))&&(year % 100))||(!(year % 400)) ? cout << 1 : cout << 0;

  • 4의 배수이면서 100의 배수이면서 400의 배수 : 윤년

    • !(year % 4) : 4의 배수이므로 나머지가 0, false가 반환되지만 그것을 부정했으므로 true
    • year % 100 : 100의 배수이므로 나머지가 0, false
    • !(year % 400) : 400의 배수이므로 나머지가 0, false가 반환되지만 그것을 부정했으므로 true
      • true && false || true : truefalse&& 논리 연산의 결과는 false이다. 그 다음 false true|| 논리 연산의 결과는 true이다. 즉 true이므로 cout << 1 이 실행되고 윤년이다.
  • 4의 배수이면서 100의 배수이면서 400의 배수가 아님 : 윤년이 아님

    • true && false || false : 결과값은 false이므로 윤년이 아니다.
  • 4의 배수이면서 100의 배수가 아님 : 윤년

    • true && true || false : 결과값은 true이다. 따라서 윤년
  • 4의 배수가 아님 : 윤년이 아님

    • false && true || false : 결과값은 false이다. 따라서 윤년이 아님.
profile
https://oraange.tistory.com/ 여기에도 많이 놀러와 주세요
post-custom-banner

0개의 댓글