FCWPS12-1. 기초 구현 답안

모든 답안은 모범 답안이 아닌 예시 답안입니다. 제가 드리는 답안 중에 종종 숏코딩이 있을 수 있습니다. 숏코딩은 가독성 측면에서는 매우 안좋기 때문에 자제 해야하지만, 라이브러리를 익히거나 여러 아이디어를 줄 수 있기에 적절하게 수용하는 것이 중요합니다.

이번 과제의 핵심은 Python이 가지고 있는 자료형과 내장함수를 PS에 적용하는 과제였습니다.

A. 나머지

해설 및 포인트

이 문제는 나머지의 순서에 관련된 문제입니다. 나머지(모듈러) 연산에서 알아두어야 할 몇가지 포인트를 담고 있습니다.

모듈러 연산은 다음과 같은 성질을 바탕이 있습니다.

source code

A, B, C = map(int, input().split())
print((A+B)%C)
print((A%C + B%C)%C)
print((A*B)%C)
print((A%C * B%C)%C)

B. !밀비 급일

해설 및 포인트

어떤 종료 조건이 나올 때까지 입력을 받아야 하는 문제입니다. 이런 경우에는 입력 조건을 먼저 해결한 후에 코드를 작성하는 것이 좋습니다.

여기서는 'END'가 들어오기 전까지 입력을 받으니 다음과 같이 작성할 수 있습니다.

while True : 
    s = input()
    if s == 'END' : break

두 번째는 문자열을 거꾸로 출력하는 방법입니다. 앞으로 배열 및 문자열을 거꾸로 하는 연산은 자주 필요합니다.

list의 reverse 메서드나 내장함수 reversed를 사용할 수 있습니다. 출력시에는 각각 join을 사용하여 붙여줘야 합니다.

s = 'abcd'
s_list = list(s) # list로 변환 
s_list.reverse() # 역순
print(''.join(s_list)) # list to string

s_rev = reversed(s)
print(''.join(s_list)) # reversed object to string

하지만 python에는 list와 string의 간격을 지정하여 slicing하는 방법이 있고, 이를 이용하면 쉽게 역순을 만들 수 있습니다.

s = s[::-1]

이런 slicing은 numpy나 pandas 등 데이터 분석에서 많이 사용됩니다.

source code

while True:
    S = input()
    if S == 'END' : break
    print(S[::-1])

C. 단어의 개수

해설 및 포인트

이 문제는 Python 활용 문제이기도 합니다.

input().split()을 사용하면 공백 기준으로 입력을 나누게 되고, 단어 리스트를 만들 수 있습니다. 그리고 내장함수 len()을 사용하여 총 개수를 구하면 됩니다.

텍스트 전처리에서 많이 사용하는 split, find, lstrip, rstrip, strip, replace 나 정규표현식 re 등은 틈틈히 연습을 해둡시다.

source code

print(len(input().split()))

D. 나머지

해설 및 포인트

이 문제는 중복된 나머지를 제거하는 문제입니다. 가장 naive하게 해결하는 방법은 두 가지 입니다.

하지만 set을 사용하면 자동으로 중복 요소를 제거하니 이를 이용하면 됩니다. 단 이런 문제에서 무작정 set을 사용하기 보다는 set에서 중복요소를 제거할 때 시간이 얼마나 걸릴지 찾아보면 좋습니다.

이 문제는 comprehension 표기로 한줄로 작성이 가능합니다. 입력이 여러 개 일때는 반복문으로 하나씩 list에 추가하기 보다는 comprehension 방법을 사용해봅시다.

source code

print(len({int(input())%42 for _ in range(10)}))

E. 알파벳 찾기

해설 및 포인트

이 문제는 여러가지 방법이 있습니다.

  1. 길이 26인 list를 만들어 ord 등을 사용해 index를 적절하게 치환
  2. dict 사용

chrord는 ASCII code 변환 관련으로 종종 나오는 문제이니 살펴봅시다.

source code

dict의 순서를 확실하게 보장하고 싶다면 collections 라이브러리의 OrderedDict를 사용할 수 있습니다.

dict의 key와 value는 따로 뽑아 사용할 수 있다는 점을 이용한 풀이 입니다.

S = input()

ans = {chr(ord('a')+i): -1 for i in range(26)}

for idx, i in enumerate(S):
    if ans[i] == -1:
        ans[i] = idx

print(' '.join(map(str, ans.values())))

F. 나는 요리사다

해설 및 포인트

이 문제는 sum을 이용하여 쉽게 합을 구하고, O(N)으로 max값과 그 값의 index를 구하는 문제입니다.

O(N)으로 max와 index를 구하는 문제는 꽤 많이 나오는 후처리(post-processing) 중 하나입니다.

여기서는 N = 5로 고정이 되어있고 매우 작은 값이므로 정렬을 사용하여 해결할 수도 있습니다. tuple의 정렬을 사용하면 값과 index가 함께 저장되므로 저장이 편리합니다.

단, 시간복잡도는 정렬을 사용하니 O(NlogN)로 는다는 점은 잊지 마세요. (N이 커지면 이렇게 하면 안됩니다.)

source code

lst = [(sum(map(int, input().split())), idx+1) for idx in range(5)]
lst.sort()
print(lst[-1][1], lst[-1][0])

G. 윤년

해설 및 포인트

윤년을 구하는 문제는 너무 유명한 문제입니다. 후에 날짜 계산, 요일 계산 문제에서도 꽤 많이 나오는 문제이므로 한 번쯤은 살펴보면 좋습니다.

포인트는 조건문을 사용할 때, 모든 조건별로 일일히 indent를 사용하여 나누지 말고 andor 연산으로 잘 쓰는 것을 연습하는 것입니다.

가장 중요한 것은 가독성이니, 본인이 생각하기에 적절하게 조건문을 작성해봅시다.

source code

어쩌다가 안 포인트인데, int(True)는 1이고, int(False)는 0입니다. 이를 사용하면 좀 더 쉽게 쓸 수 있습니다.

year = int(input())
print(1 if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 else 0)