티스토리 뷰
백준 1283번 단축키 지정 Python
문제
문제
한글 프로그램의 메뉴에는 여러 개의 옵션이 있으며, 각 옵션은 하나 혹은 여러 개의 단어로 구성되어 있습니다.
우리는 각 옵션마다 대표 알파벳 하나를 단축키로 지정해야 합니다.
이 단축키는 중복될 수 없으며, 대소문자를 구분하지 않습니다.
테스트케이스
예제 입력 1
5
New
Open
Save
Save As
Save All
예제 출력 1
[N]ew
[O]pen
[S]ave
Save [A]s
Sa[v]e All
예제 입력 2
8
New window
New file
Copy
Undo
Format
Font
Cut
Paste
예제 출력 2
[N]ew window
New [f]ile
[C]opy
[U]ndo
F[o]rmat
Fon[t]
Cut
[P]aste
문제설명
각 옵션마다 단축키를 정하는 규칙은 다음과 같습니다.
- 각 옵션의 단어를 왼쪽에서 오른쪽으로 확인합니다.
- 각 단어의 첫 글자를 차례대로 살피며,
아직 단축키로 지정되지 않은 알파벳이 있으면 그 글자를 단축키로 지정합니다. - 만약 모든 단어의 첫 글자가 이미 사용된 경우,
옵션 문자열 전체를 왼쪽에서 오른쪽으로 한 글자씩 탐색하면서
단축키로 지정되지 않은 첫 글자를 단축키로 지정합니다. - 모든 글자가 이미 단축키로 지정된 경우에는 원문 그대로 출력합니다.
단축키로 지정된 글자는 [ ] 대괄호로 감싸 표시합니다.
대소문자는 구분하지 않으며, 이미 지정된 알파벳은 다시 쓸 수 없습니다.
문제 풀이 아이디어
이 문제는 각 옵션을 순서대로 처리하면서,
이미 사용된 알파벳을 저장해 중복을 방지하는 방식으로 해결합니다.
핵심 변수는 다음과 같습니다.
- arr: 입력된 옵션 문자열들을 저장하는 리스트
- dic: 이미 단축키로 사용된 알파벳을 기록하는 딕셔너리
- Check: 단축키를 현재 옵션에서 찾았는지 여부
- Check2: 두 번째 탐색(전체 문자 탐색) 시 단축키를 찾았는지 여부
입력 처리
입력 예시:
5
New
Open
Save
Save As
Save All
처리 후:
arr = ["New", "Open", "Save", "Save As", "Save All"]
dic = {}
동작 흐름 (전체 옵션 기준)
① 첫 번째 옵션 "New"
- 단어 리스트: ["New"]
- 첫 단어 첫 글자 'N'은 아직 dic에 없음 → 등록
- 출력 결과: [N]ew
- dic = {'n': 1}
② 두 번째 옵션 "Open"
- 단어 리스트: ["Open"]
- 'O'는 아직 등록 안 됨 → 등록
- 결과: [O]pen
- dic = {'n': 1, 'o': 1}
③ 세 번째 옵션 "Save"
- 단어 리스트: ["Save"]
- 'S'는 아직 등록 안 됨 → 등록
- 결과: [S]ave
- dic = {'n': 1, 'o': 1, 's': 1}
④ 네 번째 옵션 "Save As"
- 단어 리스트: ["Save", "As"]
- 'S'는 이미 등록됨 → 다음 단어 "As"로 이동
- "As"의 첫 글자 'A'는 등록 안 됨 → 등록
- 결과: Save [A]s
- dic = {'n': 1, 'o': 1, 's': 1, 'a': 1}
⑤ 다섯 번째 옵션 "Save All"
- 단어 리스트: ["Save", "All"]
- 'S', 'A' 모두 이미 등록되어 있음
- → 첫 글자 규칙으로는 단축키를 지정할 수 없음
- 따라서 문자열 전체를 왼쪽부터 한 글자씩 탐색 시작
“Save All”의 실제 판단 기준
이 시점이 핵심입니다. "Save All"을 처리할 때,
코드는 각 글자를 순서대로 확인하며 다음 규칙으로 판단합니다.
- 공백은 무시합니다.
- 알파벳이 이미 등록되어 있으면 건너뜁니다.
- 처음 발견되는 미등록 알파벳이 단축키로 지정됩니다.
실제 흐름
현재 dic = {'n':1, 'o':1, 's':1, 'a':1}
"Save All"의 각 문자별 검사 결과는 다음과 같습니다.
결국 ‘v’가 처음 발견된 미등록 알파벳이므로
단축키로 지정됩니다.
결과:
Sa[v]e All
딕셔너리 갱신:
dic = {'n': 1, 'o': 1, 's': 1, 'a': 1, 'v': 1}
“Save Save”의 실제 판단 기준
이 경우는 더욱 복잡한 분기 구조를 가집니다.
하나하나 코드를 따라가며 어떤 판단이 내려지는지 살펴보겠습니다.
현재 상태:
dic = {'n':1, 'o':1, 's':1, 'a':1, 'v':1}
입력 문자열:
Save Save
(1) 옵션 분리
sts = arr[i].split() → ["Save", "Save"]
두 단어로 분리됩니다.
(2) 첫 번째 단어 판단
코드의 첫 판단 기준은 다음과 같습니다.
if sts[j][0].lower() not in dic and Check:
현재 sts[0][0] → 'S',
's'는 이미 등록되어 있습니다.
따라서 이 조건은 거짓(False)이 되어,
이 단어는 단축키로 지정되지 않습니다.
현재 상태:
st = "Save"
Check = True
즉, 아직 단축키를 찾지 못했기 때문에 다음 단어로 넘어갑니다.
(3) 두 번째 단어 판단
sts[1][0] → 'S',
역시 's'는 이미 등록되어 있으므로 조건이 거짓(False)입니다.
따라서 두 번째 단어도 단축키로 지정할 수 없습니다.
현재 상태 그대로 유지:
st = "Save Save"
Check = True (아직 단축키 없음)
이제 단어 첫 글자로 지정하는 첫 번째 규칙은 실패했습니다.
(4) 두 번째 판단 기준 — 전체 문자 탐색
다음 코드 블록으로 진입합니다.
if Check:
NN = len(arr[i])
for j in range(NN):
if arr[i][j].lower() not in dic and arr[i][j] != ' ':
이 구문은 문자열 전체를 왼쪽부터 하나씩 탐색합니다.
(5) 글자 단위 탐색
문자열 "Save Save"를 순서대로 탐색합니다.
즉, 'e'가 등록되지 않은 첫 글자입니다.
따라서 단축키는 'e'로 지정됩니다.
결과 문자열:
Sav[e] Save
딕셔너리 갱신:
dic = {'n':1, 'o':1, 's':1, 'a':1, 'v':1, 'e':1}
(6) 탐색 종료
Check2=False로 바뀌며 반복이 끝나고,
단축키를 지정한 옵션이 출력됩니다.
최종 결과:
Sav[e] Save
코드
N=int(input())
arr=[]
dic={}
for _ in range(N):
arr.append(input())
for i in range(N):
sts=arr[i].split()
n=len(sts)
Check=True
Check2=True
st=''
for j in range(n):
if sts[j][0].lower() not in dic and Check:
dic[sts[j][0].lower()] = 1
if st!='':
st+=" "+f'[{sts[j][0]}]{sts[j][1:]}'
else:
st += f'[{sts[j][0]}]{sts[j][1:]}'
Check=False
else:
if st=='':
st+=sts[j]
else:
st+=" "+sts[j]
if not Check:
print(st)
if Check:
NN=len(arr[i])
for j in range(NN):
if arr[i][j].lower() not in dic and arr[i][j]!=' ':
dic[arr[i][j].lower()]=1
print(f'{arr[i][:j]}[{arr[i][j]}]{arr[i][j+1:]}')
Check2=False
break
if Check and Check2:
print(arr[i])
결론
이 문제의 핵심은 단축키 우선순위 판단 구조입니다.
- 각 단어의 첫 글자를 순서대로 검사하여 미등록 알파벳을 찾습니다.
- 모든 첫 글자가 이미 사용된 경우,
문장 전체를 왼쪽부터 순서대로 스캔하며 가장 먼저 발견되는 미등록 글자를 선택합니다. - 알파벳의 대소문자는 구분하지 않으며, 한 번 지정된 글자는 다시 사용할 수 없습니다.
이 로직에 따라 "Save All"은 Sa[v]e All,
"Save Save"는 Sav[e] Save처럼 처리됩니다.
즉, 코드의 핵심 판단 기준은 “이미 등록된 알파벳인지 여부”를 검사한 뒤,
등록되지 않은 첫 번째 글자에 즉시 대괄호를 삽입하는 것입니다.
'백준 스터디' 카테고리의 다른 글
| 14426번 접두사 찾기 (0) | 2025.11.02 |
|---|---|
| 백준 1337, 올바른 배열 (0) | 2025.10.28 |
| 백준 1138번 한 줄로 서기 Python (0) | 2025.10.26 |
| 백준 1235 학생 번호 Python (0) | 2025.10.24 |
| 백준 10830번 행렬 제곱 Python (0) | 2025.10.24 |
- Total
- Today
- Yesterday
- 문자열처리
- 코딩테스트
- 코딩 테스트
- 알고리즘 문제풀이
- c언어
- 알고리즘기초
- 백준
- 그리디
- dfs
- 상속
- DP
- Python
- 동적계획법
- C++
- 파이썬
- 알고리즘
- 자바
- 프로그래머스
- 객체지향
- 브루트포스
- 문제 풀이
- 그리디알고리즘
- 파이썬코딩
- 프로그래밍
- python 알고리즘
- 동적 계획법
- 코딩
- 문제풀이
- 알고리즘문제풀이
- 그래프 탐색
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |
