구현 문제!
처음에는 엄청 간단하게만 생각했는데, 아니었다. 생각해야 할 게 많았다..
나는 한 명씩 거짓말쟁이로 가정하고, 정답이 될 수 있는 것들을 다 모았다.
정답이 될 수 있는 게 하나라면, 정답으로 출력하면 된다.
정답이 될 수 있는 게 없거나, 여러 개라면 정답이 확정이 안되는 것이니까 -1를 출력하면 된다.
한 명을 거짓말쟁이로 가정한 상태에서 정답이 뭐가 될 수 있는지 봐주기 위해서, 매번 baseman_arr 리스트를 만들었다. 1번~ 9번에 대해서, 1루수라고 하는지 아니라고 하는지를 저장했따. 초기값은 -1로 해둔 후에, 해당 번호의 사람이 1루수라고 하면 1을, 아니라고 하면 0을 저장했다.
모순이 생긴다면 바로 break를 했고, 그렇지 않다면 모든 사람의 말을 들어본 후에 baseman_arr를 봐주었다. baseman_arr에서 1루수라는 표시가 1개라면, 그 번호가 정답이 될 수 있다고 모았다. baseman_arr에서 1루수라는 표시가 없으면, 아무 표시가 없는 아이들(-1)도 1루수가 될 가능성이 있으므로 정답이 될 수 있다고 모았다.
고려해야 할 것들...
- 거짓말쟁이로 가정한 사람의 이야기는 반대로 baseman_arr에 저장해야 한다.
- 거짓말쟁이의 말과 똑같이 말하는 사람이 있으면, 모순이 된다.
- 거짓말쟁이가 아닌 경우.
- 맞다고 증언한 사람이 있는데(baseman_arr가 1), 아니라는 사람이 있으면 모순
- 아니라고 증언한 사람이 있는데(baseman_arr가 0), 맞다는 사람이 있으면 모순
- 게시판의 반례와 설명이 문제를 이해하는 데 큰 도움이 되었다.
코드
import sys
input = sys.stdin.readline
MIIS = lambda: map(int, input().split())
testimonies = []
for _ in range(9):
a, b = MIIS()
testimonies.append((a, b))
candidates = []
for liar in range(9): # 그 사람이 거짓말한다고 가정하고 볼 것
baseman_arr = [100] + [-1] * 9 # 각 사람들이 1루수인지?
liar_speak = [-1, -1]
for i in range(9):
is_baseman, baseman_num = testimonies[i]
if i == liar: # 거짓말 쟁이로 가정한 사람 이야기대로 말한 사람이 있으면 모순
if baseman_arr[baseman_num] == is_baseman:
break
baseman_arr[baseman_num] = (1 + is_baseman) % 2 # 거짓말의 반대
liar_speak = [is_baseman, baseman_num]
continue
# 만약 거짓말쟁이의 이야기와 똑같이 이야기하는 사람 있으면 모순
if liar_speak != -1 and liar_speak[0] == is_baseman and liar_speak[1] == baseman_num:
break
if is_baseman == 0 and baseman_arr[baseman_num] != 1: # 아니라고 증언했고, 맞다는 증언이 없으면
baseman_arr[baseman_num] = 0 # 아니라고 표시
elif is_baseman == 0 and baseman_arr[baseman_num] == 1: # 아니라고 증언했는데, 맞다는 증언이 있으면
break # 모순!
elif is_baseman == 1 and baseman_arr[baseman_num] == 0: # 맞다고 증언했는데, 아니라는 증언이 있으면
break # 모순!
elif is_baseman == 1 and baseman_arr[baseman_num] != 0: # 맞다고 증언했는데, 아니라는 증언이 없으면
baseman_arr[baseman_num] = 1 # 맞다고 표시
else: # break 안 나왔으면 baseman_arr를 쭉 보기!
if baseman_arr.count(1) == 0: # 모순이 없고, 아니라는 표시가 없으면 그 아이들 다 될 수 있음.
for j in range(1, 10):
# 그런데 거짓말쟁이 말대로는 안됨.
if j == liar_speak[1] and liar_speak[0] == 1:
continue
if baseman_arr[j] == -1:
candidates.append(j)
elif baseman_arr.count(1) == 1: # 1루수라는 표시가 1개이면
candidates.append(baseman_arr.index(1))
if len(set(candidates)) == 1:
print(candidates[0])
else: # 답 구할 수 없는 경우
print(-1)
728x90
'즐거운 PS 👩💻🥰' 카테고리의 다른 글
[백준-파이썬] 5710:전기 요금 (0) | 2022.02.03 |
---|---|
[백준-파이썬] 20157: 화살을 쏘자! (0) | 2022.01.26 |
[백준-파이썬] 11779: 최소 비용 구하기2 (0) | 2022.01.13 |
[백준-파이썬] 9465: 스티커 (0) | 2021.12.31 |
[백준-파이썬] 1874: 스택 수열 (0) | 2021.12.31 |