[백준] 14653 - 너의 이름은

2021. 8. 7. 17:36·알고리즘 (PS)/BOJ
반응형

https://www.acmicpc.net/problem/14653

 

14653번: 너의 이름은

첫째 줄에 OAKAK TALK방에 있는 사람 수 N과 총 메시지의 개수 K, 정보를 알고 싶은 메시지의 번호 Q가 주어진다. (1 ≤ N ≤ 26, 1 ≤ K ≤ 10,000, 1 ≤ Q ≤ K) 둘째 줄부터 K개의 줄에 걸쳐 메시지를 읽지

www.acmicpc.net

알고리즘 분류는 문자열, 구현으로 되어있다.

구현 문제가 맞기는 한데, 개인적으로 실버5 난이도보다는 살짝 높은 난이도의 구현이라고 생각했다.


풀이 아이디어


이 문제는 메세지를 보낸 사람과 그 메세지를 읽지 않은 사람의 숫자가 주어질 때,

임의로 선택한 메세지를 읽지 않은 가능성이 있는 사람을 모두 찾는 문제이다.

 

처음 이 문제를 봤을 때는 풀이 방법이 잘 감이 오지 않았지만,

입력으로 주어지는 메세지의 숫자에서 힌트를 얻었다.

 

제한시간이 2초인데, 입력으로 들어오는 메세지의 숫자가 10000이다.

그렇다면 O(n^2) 의 시간복잡도로도 충분히 풀 수 있다는 뜻이다.

그리고 이 문제의 핵심은 바로 이 문장이다.

 

"만약 어떤 시점에 메시지를 읽거나 보냈다면, 그 시점 이전에 수신된 메시지는 모두 읽은 것으로 처리된다."

 

처음에는 문제에서 주어진 '읽지 않은 사람의 숫자'가 현재 메세지를 보낸 시점에서 읽지 않은 사람의 숫자인지,

아니면 전체 총 메세지에 대해서 읽지 않은 사람의 숫자인지 헷갈렸었다.

이 문제는 후자를 의도하고 낸 문제이다.

 

그렇다면 풀이 방법은 매우 간단해지는데, 아래의 알고리즘을 사용하면 된다.

 

1. 어떤 사람이 메세지를 읽을 때마다, 그 앞의 메세지를 읽은 사람에 그 사람을 추가해주면 된다.

 

나는 이걸 구현하기 위해 집합(set)을 사용했다.

2 A

2 B

2 A

2 B

와 같은 입력이 주어진다면, B를 중복해서 넣을 우려가 있기 때문이다.

(문제에서 A는 항상 읽는다고 했기 때문에, A는 고려하지 않았다.)

 

그런데 이렇게만 풀면 문제를 틀리게 된다.

다음과 같은 반례가 있기 때문이다.

 

5 4 3

2 A

2 B

2 A

3 C

 

상기한 첫번째 파트만 알고리즘에 적용하면,

3번째 메세지를 읽지 않은 사람 후보로 B D E 를 출력하지만, 실제 답은 D, E 이다.

2번째에서 B가 읽었다는 것을 확인한 상태에서,

3번째에 읽지 않은 사람의 숫자가 변하지 않았다는 말은, B는 계속해서 읽고 있었다는 뜻이다.

 

이게 성립되는 이유는 '메세지를 읽지 않은 사람의 숫자'가

"전체 총 메세지에 대해서 읽지 않은 사람의 숫자" 이기 때문이다.

 

2번째까지 B가 읽고, 3번째에서 B가 읽지 않았다고 가정해보면,

읽지 않은 사람의 숫자는 반드시 증가했어야 한다.

 

만약 B가 3번째에 읽지 않았다가 한참 나중에 읽었다고 한다면,

나중에 메세지를 읽는 순간, 3번째 메세지도 B가 읽은 것으로 처리되기 때문에,

"전체 총 메세지에 대해 읽지 않은 사람의 숫자"에 B가 읽은 것이 반영되어있어야 한다.

따라서 다음 알고리즘이 추가되어야 한다.

 

2. 만약 읽지 않은 사람의 숫자가 이전 메세지와 같다면,

이전 메세지의 '읽지 않은 사람 목록'과 현재 메세지의 '읽지 않은 사람의 목록'은 같다.

 

이 두가지를 고려하여 알고리즘을 작성하면 문제를 풀 수 있다.


소스 코드


import sys, copy
input = sys.stdin.readline
people, message, checkingMessage = map(int, input().split())
whoRead = [{'A'} for _ in range(message)]
notReadCount = []
for i in range(message):
    notRead, sender = input().split()
    notReadCount.append(int(notRead))

    # 보낸 사람이 A가 아니면 내가 메세지를 보내기 위해서 앞의 모든 메세지를 읽었어야 하므로 앞에 읽은 모든 메세지에 나를 추가
    if sender != 'A':
        for j in range(0, i):
            whoRead[j].add(sender)

    # 읽지 않은 사람의 숫자가 그대로라면, 직전 상태와 현재 상태가 같다는 의미이다.
    if i > 0 and notReadCount[i] == notReadCount[i-1]:
        whoRead[i] = copy.deepcopy(whoRead[i-1])

    # 현재 메세지를 읽은 사람에 나를 추가
    whoRead[i].add(sender)


if notReadCount[checkingMessage-1] == 0:
    print(-1)
else:
    for i in range(people):
        if chr(ord('A') + i) not in whoRead[checkingMessage-1]:
            print(chr(ord('A') + i), end=' ')
반응형
저작자표시 비영리 변경금지 (새창열림)

'알고리즘 (PS) > BOJ' 카테고리의 다른 글

[백준] 2376 - 단말 정점들의 거리 (P5)  (0) 2021.08.14
[백준] 11054 - 가장 긴 바이토닉 부분 수열 (G3)  (0) 2021.08.10
[백준] 9465 - 스티커  (0) 2021.07.29
[백준] 2437 - 저울  (0) 2021.07.17
[백준] 15815 - 천재 수학자 성필  (0) 2021.07.10
'알고리즘 (PS)/BOJ' 카테고리의 다른 글
  • [백준] 2376 - 단말 정점들의 거리 (P5)
  • [백준] 11054 - 가장 긴 바이토닉 부분 수열 (G3)
  • [백준] 9465 - 스티커
  • [백준] 2437 - 저울
에버듀
에버듀
개발은 좋은데 뭘로 개발할까
  • 에버듀
    Blog. 에버듀
    에버듀
  • 전체
    오늘
    어제
    • 분류 전체보기 (615) N
      • 개인 프로젝트 (43)
        • 토이 프로젝트 (3)
        • [2020] 카카오톡 봇 (9)
        • [2021] 코드악보 공유APP (22)
        • [2022] 유튜브 뮤직 클론코딩 (9)
        • [2025] 한글 SQL 데이터베이스 (0)
      • 팀 프로젝트 (22)
        • [2020] 인공지능 숫자야구 (4)
        • [2022] OSAM 온라인 해커톤 (10)
        • [2024] GDSC 프로젝트 트랙 (6)
        • [2025] 큰소리 웹 페이지 (2)
      • CS (335)
        • 자료구조 (19)
        • 어셈블리 (41)
        • 멀티미디어응용수학 (7)
        • 컴퓨터 구조 (29)
        • 알고리즘 분석 (4)
        • 컴퓨터 네트워크 (38)
        • 프로그래밍언어론 (15)
        • HCI 윈도우즈프로그래밍 (26)
        • 기초데이터베이스 (29)
        • 운영체제 (23)
        • 오토마타 (24)
        • 문제해결기법 (11)
        • 블록체인 (22)
        • 소프트웨어공학 (21)
        • 기계학습심화 (12)
        • 컴퓨터그래픽스와 메타버스 (8)
        • 분산시스템특론 (6)
      • 자기계발 (45) N
        • 생각 정리 (23) N
        • 대외활동 (11)
        • 동아리 (7)
        • 자격증 (3)
        • 머니 스터디 (1)
      • 알고리즘 (PS) (107)
        • BOJ (101)
        • Programmers (5)
        • 알고리즘 이모저모 (1)
      • WEB(BE) (8)
        • express.js (1)
        • Spring & Spring Boot (7)
      • WEB(FE) (2)
        • html, css, js (1)
        • React.js (1)
      • Tool & Language (6)
        • Edit Plus (1)
        • Git (1)
        • Python3 (2)
        • Java (2)
      • Infra (12)
        • AWS (1)
        • Oracle Cloud (8)
        • Firebase (2)
        • Network (1)
      • Android (18)
        • Java (6)
        • Flutter (12)
      • Window (2)
        • Visual Studio 없이 WPF (1)
        • MFC (1)
      • 독서 (14)
        • Inside Javascript (7)
        • Database Internals (6)
        • 한 글 후기 (1)
  • 링크

    • github
    • website
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에버듀
[백준] 14653 - 너의 이름은
상단으로

티스토리툴바