ํ์ด ์ ๊ทผ
์ด ๋ฌธ์ ๋ ํธ๋ผ์ด ์๋ฃ๊ตฌ์กฐ๋ก ํ์ดํ ์ ์๋ค.
ํ์ด๋ฒ 1(์๊ฐ์ด๊ณผ)
- ์ฌ์ (dictionary)์ ๋จ์ด์ ๋ํด ํธ๋ผ์ด๋ฅผ ์ด๊ธฐํํ๋ค.
- DFS ํ์
- ์ง๊ธ๊น์ง ๋ฐฉ๋ฌธํ ๋จ์ด์ ์์๋ก ๋ง๋ค์ด์ง ๋ฌธ์์ด(
l)์ด ํธ๋ผ์ด์ ์๋์ง ํ์ธ l๋ก ์์ํ๋ ๋จ์ด๊ฐ ํธ๋ผ์ด์ ์์ผ๋ฉด DFS ์ข ๋ฃ(์ต์ ํ)
- ์ง๊ธ๊น์ง ๋ฐฉ๋ฌธํ ๋จ์ด์ ์์๋ก ๋ง๋ค์ด์ง ๋ฌธ์์ด(
- ํธ๋ผ์ด์ ์กฐํ๋ ๋จ์ด ์ ์ฅ
ํธ๋ผ์ด ๊ตฌํ
ํธ๋ผ์ด๊ฐ ๋ญ์ง?
class TrieNode:
def __init__(self, character=None):
self.c = character
self.children = {}
self.is_end = False # ์ด ๊ธ์๊ฐ ๋ง์ง๋ง์ธ ๋ฌธ์์ด์ด ์กด์ฌํจ์ ๋ํ๋ด๋ Flag
class Trie:
def __init__(self):
self.head = TrieNode()
def add(self, string):
if len(string) == 0:
return
current = self.head
for c in string:
if c not in current.children:
current.children[c] = TrieNode(c)
current = current.children[c]
current.is_end = True
def search(self, string):
current = self.head
for c in string:
if c not in current.children:
return False
current = current.children[c]
return current.is_end
def is_prefix(self, string):
current = self.head
for c in string:
if c not in current.children:
return False
current = current.children[c]
return True์ ์ญ ๋ณ์์ ๋ก์ง ํ๋ฆ
dx = [-1, -1, 0, 1, 1, 1, 0, -1]
dy = [0, 1, 1, 1, 0, -1, -1, -1]
board = list() # ์ด์ฐจ์ ๋ฆฌ์คํธ
found = set() # ๋ณด๋์์ ๋ฐ๊ฒฌํ ๋ฌธ์์ด ์งํฉ
visited = [[False for _ in range(4)] for _ in range(4)]
# ๋ก์ง ํ๋ฆ
# ํธ๋ผ์ด ์ด๊ธฐํ
trie = Trie()
for _ in range(int(input())):
trie.add(input().strip())
input()
# ๋ณด๋๋ณ ์ ๋ต ๊ตฌํ๊ธฐ
n = int(input())
for i in range(n):
board = [list(input().strip()) for _ in range(4)]
found = set()
visited = [[False for _ in range(4)] for _ in range(4)]
play_game()
if i != n - 1:
input()์ถ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๊ตฌํ๋ ๋ก์ง ํ๋ฆ
def play_game():
global found
scores = 0
find_word() # ํด๋น ๋ณด๋์์ ์ป์ ์ ์๋ ๋จ์ด ์ฐพ๊ธฐ
found = list(found) # ์ ๋ ฌ์ ์ํด ์งํฉ์ ๋ฆฌ์คํธ๋ก ๋ณํ
found.sort(key= lambda w: (-len(w), w))
for word in found:
scores += get_score(word)
print(scores, found[0], len(found))
returnDFS ํ์์ผ๋ก ํธ๋ผ์ด ์กฐํ
# DFS
def find(x, y, chars: list): # chars: ํ์ฌ๊น์ง ์์๋๋ก ๋ฐฉ๋ฌธํ ์ํ๋ฒณ ๋ฆฌ์คํธ
# ๊ธธ์ด ์ด๊ณผ์
if len(chars) > 8:
return
# ์ฌ์ ์ ์๋ ๋จ์ด์ธ์ง ํ์ธ
target = ''.join(chars)
# ์กด์ฌํ์ง ์๋ prefix๋ฉด DFS ์ข
๋ฃ
if not trie.is_prefix(target):
return
# ์กด์ฌํ๋ ๋จ์ด ์ ์ฅ
if trie.search(target):
found.add(target)
for i in range(8):
nx, ny = x + dx[i], y + dy[i]
if is_range(nx, ny) and not visited[nx][ny]:
visited[nx][ny] = True
chars.append(board[nx][ny])
find(nx, ny, chars)
visited[nx][ny] = False
chars.pop()
def find_word() -> None:
for i in range(4):
for j in range(4):
visited[i][j] = True
find(i, j, [board[i][j]])
visited[i][j] = False
returnํ์ด๋ฒ2(ํธ๋ผ์ด ์กฐํ ์ต์ ํ)
๋งค DFS๋ง๋ค prefix์ search๋ฅผ ์ํํ๋ ๊ฒ์ด ๋นํจ์จ์ ์ด๋ค.
๊ทธ๋ผ ์ด๋ป๊ฒ ํด๊ฒฐํ ๊น?
ํธ๋ผ์ด ๋
ธ๋์ is_end(์ด ๊ธ์๊ฐ ๋ง์ง๋ง์ธ ๋ฌธ์์ด์ด ์กด์ฌํจ์ ๋ํ๋ด๋ Flag) ๋ฅผ ํ์ฉํ๋ฉด ์ต์ ํํ ์ ์๋ค.
- ๋ฃจํธ์์ ํด๋น ๊ธ์๋ฅผ ๊ฐ์ง children์ด ์๋์ง ํ์ธ
- ์ฌ๊ท: ํ์ฌ ํธ๋ผ์ด ๋
ธ๋์์ ๋ค์ ๊ธ์๋ก ์ด๋ํ ์ ์๋์ง ํ์ธ
- ๋ง์ฝ ์์์ด ์์ผ๋ฉด(prefix๊ฐ ์๋๋ฉด) ํ์ ์ข ๋ฃ
- ํ์ฌ ๋
ธ๋์
is_end๊ฐ True์ด๋ฉด, ๋จ์ด ์ ์ฅ
์ต์ข ์ฝ๋
class TrieNode:
def __init__(self, character=None):
self.c = character
self.children = {}
self.is_end = False
class Trie:
def __init__(self):
self.head = TrieNode()
def add(self, string):
if len(string) == 0:
return
current = self.head
for c in string:
if c not in current.children:
current.children[c] = TrieNode(c)
current = current.children[c]
current.is_end = True
import sys
input = sys.stdin.readline
dx = [-1, -1, 0, 1, 1, 1, 0, -1]
dy = [0, 1, 1, 1, 0, -1, -1, -1]
board = list() # ์ด์ฐจ์ ๋ฆฌ์คํธ
found = set() # ๋ณด๋์์ ๋ฐ๊ฒฌํ ๋ฌธ์์ด
visited = [[False for _ in range(4)] for _ in range(4)]
def get_score(string: str):
length = len(string)
if length <= 2:
return 0
elif length <= 4:
return 1
elif length == 5:
return 2
elif length == 6:
return 3
elif length == 7:
return 5
return 11
def is_range(x, y):
return 0 <= x < 4 and 0 <= y < 4
# DFS
def find(x, y, node, word):
if node.is_end:
found.add(word)
# ๊ธธ์ด ์ด๊ณผ์
if len(word) >= 8:
return
for i in range(8):
nx, ny = x + dx[i], y + dy[i]
if is_range(nx, ny) and not visited[nx][ny]:
c = board[nx][ny]
# ํด๋น ๊ธ์๊ฐ ์์ ๋
ธ๋๋ก ์กด์ฌํ๋ฉด ํ์ ์งํ
if c in node.children:
visited[nx][ny] = True
find(nx, ny, node.children[c], word + c)
visited[nx][ny] = False
def find_word() -> None:
for i in range(4):
for j in range(4):
c = board[i][j]
# ํด๋น ๊ธ์๊ฐ ์์ ๋
ธ๋๋ก ์กด์ฌํ๋ฉด ํ์ ์งํ
if c in trie.head.children:
visited[i][j] = True
find(i, j, trie.head.children[c], c)
visited[i][j] = False
def play_game():
global found
scores = 0
find_word()
found = list(found)
found.sort(key= lambda w: (-len(w), w))
for word in found:
scores += get_score(word)
print(scores, found[0], len(found))
trie = Trie()
for _ in range(int(input())):
trie.add(input().strip())
input()
n = int(input())
for i in range(n):
board = [list(input().strip()) for _ in range(4)]
found = set()
visited = [[False for _ in range(4)] for _ in range(4)]
play_game()
if i != n - 1:
input()