티스토리 뷰

백준 스터디

백준 1283번 단축키 지정 Python

박완희버서커 2025. 10. 28. 14:44
반응형

백준 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



문제설명

각 옵션마다 단축키를 정하는 규칙은 다음과 같습니다.

  1. 각 옵션의 단어를 왼쪽에서 오른쪽으로 확인합니다.
  2. 각 단어의 첫 글자를 차례대로 살피며,
    아직 단축키로 지정되지 않은 알파벳이 있으면 그 글자를 단축키로 지정합니다.
  3. 만약 모든 단어의 첫 글자가 이미 사용된 경우,
    옵션 문자열 전체를 왼쪽에서 오른쪽으로 한 글자씩 탐색하면서
    단축키로 지정되지 않은 첫 글자를 단축키로 지정합니다.
  4. 모든 글자가 이미 단축키로 지정된 경우에는 원문 그대로 출력합니다.

단축키로 지정된 글자는 [ ] 대괄호로 감싸 표시합니다.
대소문자는 구분하지 않으며, 이미 지정된 알파벳은 다시 쓸 수 없습니다.




문제 풀이 아이디어

이 문제는 각 옵션을 순서대로 처리하면서,
이미 사용된 알파벳을 저장해 중복을 방지하는 방식으로 해결합니다.
핵심 변수는 다음과 같습니다.

  • arr: 입력된 옵션 문자열들을 저장하는 리스트
  • dic: 이미 단축키로 사용된 알파벳을 기록하는 딕셔너리
  • Check: 단축키를 현재 옵션에서 찾았는지 여부
  • Check2: 두 번째 탐색(전체 문자 탐색) 시 단축키를 찾았는지 여부


입력 처리

입력 예시:

5
New
Open
Save
Save As
Save All

처리 후:

arr = ["New", "Open", "Save", "Save As", "Save All"]
dic = {}


동작 흐름 (전체 옵션 기준)

① 첫 번째 옵션 "New"

  1. 단어 리스트: ["New"]
  2. 첫 단어 첫 글자 'N'은 아직 dic에 없음 → 등록
  3. 출력 결과: [N]ew
  4. dic = {'n': 1}


② 두 번째 옵션 "Open"

  1. 단어 리스트: ["Open"]
  2. 'O'는 아직 등록 안 됨 → 등록
  3. 결과: [O]pen
  4. dic = {'n': 1, 'o': 1}


③ 세 번째 옵션 "Save"

  1. 단어 리스트: ["Save"]
  2. 'S'는 아직 등록 안 됨 → 등록
  3. 결과: [S]ave
  4. dic = {'n': 1, 'o': 1, 's': 1}


④ 네 번째 옵션 "Save As"

  1. 단어 리스트: ["Save", "As"]
  2. 'S'는 이미 등록됨 → 다음 단어 "As"로 이동
  3. "As"의 첫 글자 'A'는 등록 안 됨 → 등록
  4. 결과: Save [A]s
  5. dic = {'n': 1, 'o': 1, 's': 1, 'a': 1}


⑤ 다섯 번째 옵션 "Save All"

  1. 단어 리스트: ["Save", "All"]
  2. 'S', 'A' 모두 이미 등록되어 있음
  3. → 첫 글자 규칙으로는 단축키를 지정할 수 없음
  4. 따라서 문자열 전체를 왼쪽부터 한 글자씩 탐색 시작


“Save All”의 실제 판단 기준

이 시점이 핵심입니다. "Save All"을 처리할 때,
코드는 각 글자를 순서대로 확인하며 다음 규칙으로 판단합니다.

  1. 공백은 무시합니다.
  2. 알파벳이 이미 등록되어 있으면 건너뜁니다.
  3. 처음 발견되는 미등록 알파벳이 단축키로 지정됩니다.

실제 흐름
현재 dic = {'n':1, 'o':1, 's':1, 'a':1}
"Save All"의 각 문자별 검사 결과는 다음과 같습니다.

인덱스 문자 소문자 등록여부 결과
0 S s 등록됨 패스
1 a a 등록됨 패스
2 v v 미등록 선택
3 e e 미등록 탐색 종료
4 (공백) - - 무시
5 A a 등록됨 -
6 l l 미등록 -
7 l l 미등록 -

결국 ‘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"를 순서대로 탐색합니다.

인덱스 문자 소문자 등록 여부 결과
0 S s 등록됨 건너뜀
1 a a 등록됨 건너뜀
2 v v 등록됨 건너뜀
3 e e 미등록 선택

즉, '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])



결론

이 문제의 핵심은 단축키 우선순위 판단 구조입니다.

  1. 각 단어의 첫 글자를 순서대로 검사하여 미등록 알파벳을 찾습니다.
  2. 모든 첫 글자가 이미 사용된 경우,
    문장 전체를 왼쪽부터 순서대로 스캔하며 가장 먼저 발견되는 미등록 글자를 선택합니다.
  3. 알파벳의 대소문자는 구분하지 않으며, 한 번 지정된 글자는 다시 사용할 수 없습니다.

이 로직에 따라 "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
링크
«   2025/11   »
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
글 보관함
반응형