티스토리 뷰
프로그래머스 [3차] 방금그곡 Python
문제
문제
라디오에서 흘러나온 음악의 일부 멜로디를 기억한 사용자가 있다면, 그 사용자가 들은 곡이 어떤 곡인지 찾아주는 프로그램을 만드는 문제입니다.
입력으로는 사용자가 기억한 멜로디 m과 방송된 음악들의 정보 musicinfos가 주어집니다.
각 음악 정보는 다음과 같은 형식을 가집니다.
시작시간,끝시간,제목,악보음악은 시작시간부터 끝시간까지 재생되며, 악보는 1분에 1음씩 재생됩니다.
악보에 있는 음의 개수가 재생 시간보다 짧으면 반복해서 재생되고,
길면 해당 시간만큼만 재생됩니다.
음계는 12개(C, C#, D, D#, E, F, F#, G, G#, A, A#, B)이며,
‘#’이 붙은 음은 다른 음으로 취급됩니다.
조건에 맞는 음악이 여러 개라면, 재생 시간이 긴 곡을 우선 선택하고,
재생 시간이 같으면 입력된 순서가 먼저인 곡을 선택합니다.
조건에 맞는 곡이 없다면 "(None)"을 반환합니다.
테스트케이스
| 기억한 멜로디 (m) | musicinfos | 정답 |
|---|---|---|
"ABCDEFG" |
["12:00,12:14,HELLO,CDEFGAB", "13:00,13:05,WORLD,ABCDEF"] |
"HELLO" |
"CC#BCC#BCC#BCC#B" |
["03:00,03:30,FOO,CC#B", "04:00,04:08,BAR,CC#BCC#BCC#B"] |
"FOO" |
"ABC" |
["12:00,12:14,HELLO,C#DEFGAB", "13:00,13:05,WORLD,ABCDEF"] |
"WORLD" |
문제 작동원리
이 문제는 기억한 멜로디(m)가 실제로 재생된 음악 안에 포함되어 있는지를 확인하는 것입니다.
즉, 단순히 “악보에 포함되어 있느냐”가 아니라,
재생 시간만큼 실제로 이어 붙인 음악 전체 안에 멜로디가 포함되는지를 판단해야 합니다.
이를 위해 다음 개념을 사용합니다.
시간 계산:
- 시작시간과 끝시간을 분 단위로 바꿔서, 음악이 총 몇 분 재생되었는지 계산합니다.
- 예: 12:00~12:14 → 14분 재생
악보 반복:
- 악보가 짧을 경우 반복해서 재생된 전체 악보를 만듭니다.
- 예: 악보
CDEFGAB(7음) → 14분 재생이면CDEFGABCDEFGAB
‘#’음 구분 처리:
C#,D#같은 음은 각각C,D와 다른 음이므로,
구분을 위해C#을c,D#을d등으로 바꿉니다.
이렇게 하면 단순 문자열 비교로도 정확히 일치 여부를 판별할 수 있습니다.
문제 아이디어
이 문제를 해결하기 위한 전체 흐름은 다음과 같습니다.
입력 변환
m과 각 음악의 악보를 모두#처리된 음으로 변환합니다.- 예:
"C#DEFGAB"→"cDEFGAB"
시간 계산
- 시작시간과 끝시간을 시·분 단위로 분리한 후,
총 재생시간 = (끝시×60+끝분) - (시작시×60+시작분)
- 시작시간과 끝시간을 시·분 단위로 분리한 후,
실제 재생 멜로디 만들기
- 음악의 악보가 짧으면 반복해서 이어붙이고,
재생시간보다 길면 필요한 만큼만 자릅니다.
예시:
악보: CDEFGAB (7음) 재생시간: 14분 → CDEFGABCDEFGAB- 음악의 악보가 짧으면 반복해서 이어붙이고,
비교
- 변환된
m이 실제 재생 멜로디 안에 포함되어 있는지 확인합니다.
- 변환된
최장 재생시간 판별
- 조건을 만족한 곡 중에서 가장 긴 재생시간을 가진 곡을 선택합니다.
- 길이가 같다면 입력 순서상 먼저 나온 곡을 선택합니다.
결과 반환
- 일치하는 곡이 없으면
"(None)"을 반환합니다.
- 일치하는 곡이 없으면
전체코드
def sharpToletter(st):
N=len(st)
stt=''
for i in range(N):
if i+1<N and st[i+1]=='#':
stt+=st[i].lower()
elif st[i]!='#':
stt+=st[i]
return stt
def solution(m, musicinfos):
m=sharpToletter(m)
N=len(m)
max_cnt=0
max_ans=''
for musics in musicinfos:
a=musics.split(',')
# 비교 문자열
st=a[3]
st=sharpToletter(st)
n=len(st)
# 정답
ans=a[2]
# 시간계산
time=a[0].split(':')
start_time=int(time[0])*60+int(time[1])
time=a[1].split(':')
end_time=int(time[0]) * 60 + int(time[1])
t=end_time-start_time
k=''
# 완성된 문자열
for i in range(t):
k+=st[i%n]
# 최대값 계산
if m in k:
if max_cnt<t:
max_cnt=t
max_ans=ans
if max_ans == '':
return "(None)"
return max_ans
결론
이 문제는 음악 재생 시간만큼 악보를 늘린 후, 변환된 멜로디와 비교하는 문자열 문제입니다.
핵심은 C#, D# 등 #이 붙은 음을 다른 문자로 변환해 정확한 비교가 가능하도록 만드는 것입니다.
또한, 악보의 길이가 아닌 실제 재생 시간(t)을 기준으로 결과를 선택해야 합니다.
이 원리를 적용하면, 주어진 모든 테스트 케이스에서 올바른 정답을 얻을 수 있습니다.
'백준 스터디 > 프로그래머스' 카테고리의 다른 글
| 프로그래머스 지게차와 크레인 python (0) | 2025.10.19 |
|---|---|
| 프로그래머스 택배 배달과 수거하기 python (0) | 2025.10.17 |
| 프로그래머스 혼자 놀기의 달인 Python (1) | 2025.10.14 |
| 프로그래머스 스킬트리 Python (0) | 2025.10.14 |
| 프로그래머스 괄호 변환 Python (0) | 2025.10.03 |
- Total
- Today
- Yesterday
- 그리디
- c언어
- 프로그래밍
- 문제풀이
- 문자열처리
- 문제 풀이
- 객체지향
- 동적계획법
- C++
- 파이썬코딩
- c++알고리즘
- C++ 알고리즘
- 프로그래머스
- 백준
- 동적 계획법
- dfs
- 그리디알고리즘
- 코딩 테스트
- Python
- 알고리즘 문제풀이
- python 알고리즘
- 브루트포스
- 코딩테스트
- DP
- 알고리즘기초
- 그래프 탐색
- 코딩
- 알고리즘문제풀이
- 파이썬
- 알고리즘
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 31 |
