본문 바로가기
SSAFY 10기/백준_파이썬

[백준_파이썬] [🥈5] 28432 (끝말잇기)

by FE우물왕 2023. 9. 1.

 

난이도 : 실버 5

알고리즘 유형 : 구현, 문자열

문제 링크 : https://www.acmicpc.net/problem/28432

28432

 

문제 풀이과정(과 사담)

나는 이 문제를 작성일로부터 근 3주전, 2023년 8월 5일 solved.ac Grand Arena #1 2번 문제로 마주했다. 

마침 싸피에서도 알고리즘 과정을 거치고 있었고, 비대면이지만 대회에 출전해보고 싶었던 나는 호기롭게 문제에 도전 했지만 무참하게 1솔에 그치게 만든 문제이다. 

그때 짠 코드(오답임)를 보면 여러모로 어지러운데 한번 실패의 현장을 같이 보자.

N = int(input())
A_list = []
B_list = []
answer = first = last = queloc = 0
for i in range(N):
    A = input()
    A_list.append(A)
#끝말잇기 리스트

for j in range(N):
    if A_list[j] == '?': #리스트를 순회하며 ?의 인덱스를 찾으려 하였다.
        if 0 < j < N-1:
            first = A_list[j-1][-1]
            last = A_list[j+1][0]
            queloc = 1
        elif j == N-1:
            first = A_list[j - 1][-1]
            queloc = 2
        elif j == 0:
            last = A_list[j + 1][0]
            queloc = 0
# 인덱스의 위치에 따라 first, last 변수를 써서 이를 기반으로 후보 단어를 판명하려 하였다
# queloc는 flag 변수처럼 맨앞, 맨뒤, 나머지를 표시하려 하였다.

N_B = int(input())
for k in range(N_B):
    B = input()
    B_list.append(B)
# 후보 단어 리스트 
   
for o in range(N_B):
	
    if B_list[o] not in A_list:
        if queloc == 0: # ?가 맨 앞이면
            if B_list[o][-1] == last: # B의 끝단어가 last와 같다.
                answer = B_list[o]
        elif queloc == 1: # ?가 중간 이면
            if B_list[o][0] == first and B_list[o][-1] == last: 
                answer = B_list[o]
        else: # ?가 끝
            if B_list[o][0] == first:
                answer = B_list[o]
                
print(answer)

일단 변수 명도 난잡스럽고, 지금와서 다시 생각해보니 다른 풀이 법이 떠올라서, 다시 시도해 보았다.

 

 

조금 보기 좋게 만들었는데, 98% 언저리에서 indexerror를 마주했다.

왜 그랬을까 생각해보니, N = 1 일때, 즉 ?만 나와 있을 때를 간과한 것이다. 그로 인해 10번 줄에서 오류가 생긴 것이다.

그것에 대해 처리를 하니 정답이었다. 

예전에 못 풀었던 문제를 지금 풀었을때의 감정은 위스키의 향 처럼 복잡하다.

'이걸 못풀었다고?' 부터 시작해서 '그래도 실력이 늘긴 했구나.' '그 때 풀었으면 좋았을텐데' 라는 생각들이 퍼져나갔다.

그래도 결국 푼 것은 푼 것이 아니겠는가? 다음에도 다시 봤을때 쉽게 풀리는 문제들이 있으면 좋겠다.

 

 

반응형

코드

N = int(input())
N_list = []

for i in range(N):
    A = input()
    N_list.append(A)
N_dx = N_list.index('?') # ? 인덱스 변수

if N_dx == 0: #맨 앞이면??
    if N != 1: # 끝말잇기 리스트의 크기가 1이 아니면
        end = N_list[N_dx + 1][0] #? 의 끝엔 end를 
        flag = 'end' #플래그 변수 end
    else:
        flag = 'odd' 
elif N_dx == N-1: # 맨 뒤
    first = N_list[N_dx - 1][-1] # ? 앞글자
    flag = 'first' 
else: # 앞도 뒤도 아님
    first = N_list[N_dx - 1][-1] 
    end = N_list[N_dx + 1][0]
    flag = 'mid'

N_set = set(N_list) #차집합 연산을 위한 set화

M = int(input())
M_set = set()
for j in range(M):
    M_set.add(input())
M_N = M_set - N_set # 차집합 연산 = 끝말잇기에 등장하지 않은 후보 단어

M_N_list = list(M_N) # 순회를 위한 리스트화

for i in M_N_list:
    if flag == 'first': 
        if i[0] == first: # 앞글자가 first변수와 같다.
            print(i) # 그 요소를 출력
            break
    elif flag == 'end': # 뒤글자가 end 변수와 같다.
        if i[-1] == end: # 그 요소를 출력
            print(i)
            break

    elif flag == 'mid': 
        if i[0] == first and i[-1] == end: # 앞글자는 first 뒤 글자는 end와 같다.
            print(i) # 그 요소를 출력
            break
    elif flag == 'odd':
        print(i) #끝말잇기 리스트 크기가 1이면 후보에 나온 아무거나 가능.
        break

 

 


 

 

반응형