Skip to content

Commit

Permalink
2024-07-14 01:12:56
Browse files Browse the repository at this point in the history
Affected files:
.obsidian/workspace.json
src/content/blog/boj-1339-단어-수학.md
  • Loading branch information
gyunseo committed Jul 13, 2024
1 parent 89a86d1 commit 16be424
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 11 deletions.
22 changes: 11 additions & 11 deletions .obsidian/workspace.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
"type": "split",
"children": [
{
"id": "9cd648d7251dacb7",
"id": "5c7cbcec3c13656e",
"type": "tabs",
"children": [
{
"id": "12588c25489580ac",
"id": "bb9e313e9ec35bc3",
"type": "leaf",
"state": {
"type": "markdown",
Expand All @@ -22,16 +22,16 @@
]
},
{
"id": "e69a48971a0a2c37",
"id": "2b1c3a474105df20",
"type": "tabs",
"children": [
{
"id": "8e00635bfc168bc5",
"id": "71e0df042bc7a561",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "src/content/blog/boj-2011-암호코드.md",
"file": "src/content/blog/boj-1339-단어-수학.md",
"mode": "source",
"source": false
}
Expand Down Expand Up @@ -103,7 +103,7 @@
"state": {
"type": "backlink",
"state": {
"file": "src/content/blog/boj-2011-암호코드.md",
"file": "src/content/blog/boj-1339-단어-수학.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
Expand All @@ -120,7 +120,7 @@
"state": {
"type": "outgoing-link",
"state": {
"file": "src/content/blog/boj-2011-암호코드.md",
"file": "src/content/blog/boj-1339-단어-수학.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
}
Expand All @@ -143,7 +143,7 @@
"state": {
"type": "outline",
"state": {
"file": "src/content/blog/boj-2011-암호코드.md"
"file": "src/content/blog/boj-1339-단어-수학.md"
}
}
}
Expand All @@ -166,15 +166,16 @@
"table-editor-obsidian:Advanced Tables Toolbar": false
}
},
"active": "8e00635bfc168bc5",
"active": "71e0df042bc7a561",
"lastOpenFiles": [
"src/content/blog/boj-2529-부등호.md",
"src/content/blog/boj-1339-단어-수학.md",
"src/content/blog/boj-2660-회장뽑기.md",
"src/content/blog/boj-2011-암호코드.md",
"src/content/blog/leet-code-438-find-all-anagrams-in-a-string.md",
"src/content/blog/boj-5525-ioioi.md",
"src/content/blog/leet-code-74-search-a-2d-matrix.md",
"src/content/blog/leet-code-1438-longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit.md",
"src/content/blog/boj-2660-회장뽑기.md",
"src/content/blog/leet-code-64-minimum-path-sum.md",
"src/content/blog/boj-6593-상범-빌딩.md",
"src/content/blog/왜-node에서-pino-logger를-이용한-log-io는-cpu-usage에-큰-영향이-없을까.md",
Expand All @@ -195,7 +196,6 @@
"src/content/blog/astro-paper-4.md",
"src/content/blog/implementing-a-worker-thread-pool-in-c.md",
"src/content/blog/boj-5014-스타트링크.md",
"src/content/blog/boj-random-defense.md",
"dist/assets/[email protected]",
"dist/assets/forrest-gump-quote.webp.jpg",
"dist/_astro/[email protected]",
Expand Down
103 changes: 103 additions & 0 deletions src/content/blog/boj-1339-단어-수학.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
author: Gyunseo Lee
title: "BOJ 백준 1339: 단어 수학"
pubDatetime: 2024-07-14T01:01:00+09:00
modDatetime: 2024-07-14T01:01:00+09:00
featured: false
draft: false
tags:
- PS
- BOJ
- Algorithms
- 실랜디
- 골랜디
- DFS
- Brute-Force
- Greedy
description: HashMap 자료구조의 O(1)과 List indexing O(1)의 무게는 다르다...
ogImage: ""
---

## Table of contents

## 들어가며

걸린 시간: 90분 (자력으로 풀지 못함)

사실 처음에 읽고, [BOJ 백준 2529: 부등호](boj-2529-부등호.md)가 생각이 났습니다.
그 문제는 그래도 경우의 수 pruning을 해서, backtracking으로 풀 수라도 있지, 이거는 완전 탐색이더라고요. (물론 나중에 태그까고 그리디라는 걸 알게됐지만요...)

## 접근

모든 단어에 포함된 알파벳 종류가 최대 10개이고, 숫자도 0부터9까지이니, 최대 경우의 수는 10!(대충 300만) 그리고 그 각 경우의 수 안에서 숫자로 변환해서 더하는 경우의 수라 해봤자 대략 80...
이러면 절대로 시간 안에 안 걸리겠는데? 하고 접근을 해봤습니다.

## 구현

```python
import sys
from itertools import permutations
input = sys.stdin.readline

def calc():
summation = 0
for s in stringList:
len_s = len(s)
num = 0
factor = 1
for i in range(len_s - 1, -1, -1):
num += mappingTable[ord(s[i]) - ord('A')] * factor
factor *= 10
summation += num
return summation

def DFS(level, cur_digit):
if level == numAlphabets - 1:
global ans
tmp_ans = calc()
# print(tmp_ans)
ans = max(ans, tmp_ans)
return

for i in range(10):
if isUsed[i]:
continue
isUsed[i] = True
mappingTable[ord(alphabetList[level + 1]) - ord('A')] = i
DFS(level + 1, i)
isUsed[i] = False

if __name__ == "__main__":
N = int(input().strip())
stringList = [input().strip() for _ in range(N)]
alphabetSet = set()
ans = 0
for string in stringList:
for ch in string:
alphabetSet.add(ch)

# 0 -> alphabet0, 1 -> alphabet1
alphabetList = list(sorted(alphabetSet))
numAlphabets = len(alphabetList)
isUsed = [False for _ in range(10)]
# alphabet0 -> digit0, ...
mappingTable = [-1 for _ in range(26)]
permutationCandsGen = permutations(range(10), numAlphabets)
for permutationCand in permutationCandsGen:
for idx, digit in enumerate(permutationCand):
mappingTable[ord(alphabetList[idx]) - ord('A')] = digit
ans = max(ans, calc())
# for i in range(10):
# isUsed[i] = True
# mappingTable[ord(alphabetList[0]) - ord('A')] = i
# DFS(0, i)
# isUsed[i] = False
print(ans)
```

코드를 보시면 알겠지만, 일단 DFS로 순열을 만들어도 통과가 되고, permutations library를 써도 통과가 됩니다. (단, pypy3 기준, python3는 안됩니다 ㅠ)
일단 dictionary와 같은 HashMap 자료구조로 어떤 알파벳이 어떤 숫자에 대응되는지 구현하면 안됩니다.
같은 O(1)이어도 List Indexing으로 구현하는 것이 훨씬 더 빠릅니다. (왜냐면 Hashing 알고리즘 + Probing 자체가 조금 더 많은 연산을 요하기 때문).
그리고 `calc` 함수를 보면, `**` 연산자 대신 직접 for 내에서 자릿수마다 곱하기 10제곱수를 하여 직접 계산을 했는데, 이 또한 일정 부분의 시간 복잡도 개선을 하게 됩니다.
물론 HashMap 자료구조를 List Indexing으로 바꾼 게 TLE를 받냐 마느냐를 가르게 합니다.
같은 시간 복잡도라도 자료구조의 특징에 따라 최적화를 할 수 있으니, 항상 생각을 합시다!!

0 comments on commit 16be424

Please sign in to comment.