[Python] BOJ 10807 개수 세기

Nogglee·2026년 1월 13일

문제 바로가기

문제 분석

  1. N개의 정수를 입력 받는다.
  2. 입력한 정수 중 정수 V는 몇개인지 카운트한다.

접근 방법

  1. 정수의 개수 N을 입력 받는다.
  2. N개의 정수를 공백으로 구분하여 입력 받는다.
  3. 찾으려고하는 정수 V를 입력 받는다.

결과

from collections import Counter

N = int(input())
arr = list(map(int, input().split()))

V = int(input())
counter = Counter(arr)[V]

print(counter)
  • 시간: 64ms
  • 메모리: 34876KB

배운 점

길이가 정해진 리스트

'N개의 정수를 입력받는다' 라는 문장을 리스트의 길이를 정해야한다고 해석하여
문제해결이 시간이 조금 오래 걸렸지만, 새롭게 배운 개념들도 있다.

길이가 정해진 리스트 생성

# n 만큼의 길이를 가진 리스트를 생성하여 0으로 초기화
arr = [0 for _ in range(n)]

처음엔 길이가 N만큼의 list를 생성 목적을 달성하기 위해
변수 N을 입력받아 range 인자로 사용하였다.

V값을 입력하면 자꾸만 앞에 '0'들이 붙어서 출력되어서 알아보니
리스트를 생성하고 0으로 초기화 한 값들이 포함되어서 그런 것이었다.

'0으로 초기화 된 상태에서 값을 덮어씌우면 될까?'라고 고민하다가
0으로 초기화 한다는 의미에 대하여 자세히 알아보았다.
빈 상자를 미리 만들고 물건을 하나씩 채우는 방식,
즉 인덱싱을 위해 필요한 개념이였다.

10807 문제에서는 V의 값을 '한 줄'로 입력 받기 때문에
자리를 지정하지 않고 이미 물건이 담긴 상자를 그대로 받으면 된다.
'길이가 N만큼' 이라는 조건에 꽂혀서 OverThinking을 한 것이었다.

Counter 클래스

Counter 클래스 사용법

  • collections 모듈의 Counter 클래스는 별도 패키지 설치 없이 import하여 사용할 수 있다.
  • Counter 생성자는 여러 형태의 데이터를 인자로 받는다.
    - 중복된 데이터가 저장된 배열을 인자로 넘기면 각 원소가 몇 번씩 나오는지가 저장된 객체가 반환된다.
    - 문자열을 인자로 넘기면 각 문자가 문자열에서 몇 번씩 나타나는지를 알려주는 객체가 반환된다.
from collections import Counter

Counter(["java", "python", "node", "java"])
# Counter({'java':2, 'python':1, 'node':1})

Counter("hello nogglee")
# Counter({'h':1, 'e':3, 'l':3, 'o':2, 'g':2})

Counter 클래스까지 사용하여 문제를 풀고 다른사람의 풀이법을 보니
처리 시간이 1/2인 풀이가 있어 가져와보았다.

이 문제에서는 특정 값 V 하나만 세면 되기 때문에,
모든 값의 빈도를 계산하는 Counter보다 list.count()가 더 단순하고 효율적이다.

a = int(input())
arr = list(map(int,input().split()))
n = int(input())
print(arr.count(n))

입력 조건에 대한 오해

현재 구현한 코드로 답변을 제출했을 때 통과는 했지만,
여전히 '길이가 N만큼'의 조건은 강제하지 않았다.

강제하지 않음의 예시

>>> 3
>>> 1 1 1 3
>>> 3
1

위 코드와 같이 N의 길이를 3으로 지정하고 4개의 V 값을 입력했을 때
길이를 넘어선 입력값인 3까지 인식하여 3의 개수는 1개라고 출력하고있다.

잠깐, 여기서 오해를 풀고 넘어가자.

알고리듬 문제에서 입력은, 문제 조건을 만족한다고 가정하고 구현해야한다.
'강제하지 않음의 예시'는 입력 값 자체가 문제 조건을 어긴 입력이다.

소프트웨어 공학에서 말하는 계약에 의한 설계 관점에서,
호출자가 사전 조건을 위반한 경우에 해당한다.

계약에 의한 설계

함수, 모듈, 클래스가 서로 약속을 맺는 방식을 의미한다.

  • 호출자(Caller): 이 조건을 만족하는 입력을 줄게!
  • 피호출자(Callee): 그러면 이런 결과를 보장할게!

위와 같은 약속을 '계약'이라고 칭한다.

계약을 '택배 시스템'에 빗대어 이해해보자.

  • 사전 조건: 택배 무게 20kg 이하
  • 사후 조건: 무료 배송

만약 보내는 이가 택배 무게를 20kg 초과하여 발송하였을 경우 무료 배송 조건은 보장되지 않는다.
보내는 이가 '계약 위반'을 했기 때문에 책임은 Caller에게 있다.

결론:
이번 문제에서는 입력으로 주어지는 정수의 개수가 항상 N개라고 보장하기 때문에
구현에서는 별도의 길이 검증이나 slicing 없이 입력을 그대로 리스트로 받아도 된다.

profile
Product-minded Engineer

0개의 댓글