https://www.acmicpc.net/problem/9202
9202번: Boggle
각각의 Boggle에 대해, 얻을 수 있는 최대 점수, 가장 긴 단어, 찾은 단어의 개수를 출력한다. 한 Boggle에서 같은 단어를 여러 번 찾은 경우에는 한 번만 찾은 것으로 센다. 가장 긴 단어가 여러 개
www.acmicpc.net
풀이
이전에 풀었던 백준 전설19585 와 비슷한 문제이다. 이전 문제가 단순히 트라이를 사용하는 문제라면 해당 문제는 트라이와 DFS를 같이 조합해서 푸는 문제이다.
핑계처럼 들리겠지만 오랜만에 알고리즘 푸니까 쉽게 풀지는 못했다...
풀이법은 다음과 같다.
1. 문제에서 주어진 단어들로 트라이를 생성한다.
2. 주어지는 board를 기준으로 모든 칸마다 조건을 만족하면 DFS를 수행한다.
이때 조건은 여느 DFS와 동일하게 DFS를 수행할수 있는지 (board에 위치한 문자가 트라이의 시작 노드에 위치한다면 만족) 확인한다.
추가로 해당 문제는 pypy3로 해야 겨우 통과가 가능하다.
코드
import sys
input = lambda: sys.stdin.readline().rstrip()
dir = [[-1, 0], [-1, 1], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1]]
score = [0, 0, 0, 1, 1, 2, 3, 5, 11]
def makeTrie():
tempDict = dict()
numberOfWords = int(input())
for _ in range(numberOfWords):
word = input()
now = tempDict
for c in word:
if not now.get(c):
now[c] = dict()
now = now[c]
now[0] = 1
return tempDict
def solve(x, y, now, word):
if now.get(0):
words.add(word)
visit[x][y] = True
for dir_x, dir_y in dir:
x1 = x + dir_x
y1 = y + dir_y
if 0 <= x1 < 4 and 0 <= y1 < 4:
if not visit[x1][y1]:
c = board[x1][y1]
if now.get(c):
solve(x1, y1, now.get(c), word + c)
visit[x][y] = False
dictionary = makeTrie()
input()
numberOfBoard = int(input())
for _ in range(numberOfBoard):
board = [list(input()) for _ in range(4)]
visit = [[False] * 4 for _ in range(4)]
words = set()
for x in range(4):
for y in range(4):
c = board[x][y]
if dictionary.get(c) and visit[x][y] == False:
solve(x, y, dictionary.get(c), c)
totalScore = sum([score[len(word)] for word in words])
maxLength = sorted(list(words), key=lambda x: (-len(x), x))[0]
totalWords = len(words)
print(totalScore, maxLength, totalWords)
input()
'백준' 카테고리의 다른 글
백준 21277 짠돌이 호석 (파이썬) (1) | 2024.01.02 |
---|---|
백준 22870 산책(large) (파이썬) (0) | 2023.12.31 |
백준 19585 전설 (파이썬) (1) | 2023.12.27 |
백준 16988 Baaaaaaaaaduk2 (Easy) (파이썬) (0) | 2023.09.01 |
백준 2900 프로그램(파이썬) (0) | 2023.08.25 |