[문제]

 

https://school.programmers.co.kr/learn/courses/30/lessons/17683

 

[풀이]

 

카카오 문제는 언제나 지문이 길지만, 막상 까보면 그냥 구현 문제이다. 지금까지 풀어왔던 카카오 문제와 유사한데, 정보가 긴 문자열(로그)로 주어지고, 그 로그의 정보를 해석하여 문제를 푸는 형식이다. 제한은 넉넉하다.

 

본인은 그냥 악보의 #을 따로 처리하기 번거로워서, 그냥 악보를 받고 먼저 보기 편한 방식으로 바꿔줬다(SheetMusic() 이후 ConvertSheetMusic()). 이후 반복문을 돌면서, 총 재생 시간은 몇 분인지, 노래 제목은 뭔지, 악보 구성은 어떻게 되어있는지 확인하고 검사 전 재생시간만큼 악보로 연주(?)를 해준다. 그러면 최종 검사 악보가 나오는데, 여기서 그냥 Find를 해주면 된다. -1 검사를 해도 되고 npos 검사를 실시해도 된다. 마지막으로 재생 시간이 더 길거나, 동일한 경우에는 앞서 재생된 노래를 return하기 위해 MaxPlayTime으로 조건을 판별해준다.

#include <string>
#include <vector>
#include <unordered_map>

using namespace std;
unordered_map<string, string> SheetMusicTable;

void SheetMusic()
{
    SheetMusicTable["C"] = "A";
    SheetMusicTable["C#"] = "B";
    SheetMusicTable["D"] = "C";
    SheetMusicTable["D#"] = "D";
    SheetMusicTable["E"] = "E";
    SheetMusicTable["F"] = "F";
    SheetMusicTable["F#"] = "G";
    SheetMusicTable["G"] = "H";
    SheetMusicTable["G#"] = "I";
    SheetMusicTable["A"] = "J";
    SheetMusicTable["A#"] = "K";
    SheetMusicTable["B"] = "L";
}

string ConvertSheetMusic(const string& _Input)
{
    string Result;
    for (size_t i = 0; i < _Input.length();)
    {
        string Note;
        if (i + 1 < _Input.length() && _Input[i + 1] == '#')
        {
            Note = _Input.substr(i, 2); // e.g., C#
            i += 2;
        }
        else
        {
            Note = _Input.substr(i, 1); // e.g., C
            i += 1;
        }

        auto it = SheetMusicTable.find(Note);
        if (it != SheetMusicTable.end())
        {
            Result += it->second;
        }
        else
        {
            Result += "?"; // Unknown note
        }
    }
    return Result;
}

string CreateSheetMusic(int _Miin, const string& _Score)
{
    string SheetMusic = "";
    int MaxIndex = _Score.size() - 1;
    int CurIndex = 0;
    while (_Miin--)
    {
        if (CurIndex > MaxIndex)
        {
            CurIndex = 0;
        }
        SheetMusic += _Score[CurIndex++];
    }

    return SheetMusic;
}

int MinuteCalculation(const string& _Start, const string& _End)
{
    string Start = _Start;
    string End = _End;

    int StartMin = (stoi(Start.substr(0, 2)) * 60) + stoi(Start.substr(3, 2));
    int EndMin = (stoi(End.substr(0, 2)) * 60) + stoi(End.substr(3, 2));

    return EndMin - StartMin;
}

// [1] 음악 제목 [2] 재생이 시작되고 끝난 시각 [3] 악보
// C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12개
string solution(string m, vector<string> musicinfos) 
{
    string answer = "(None)";
    SheetMusic();
    string Newm = ConvertSheetMusic(m);

    int MaxPlayTime = -1; // 현재까지의 최장 재생 시간
    for (size_t i = 0; i < musicinfos.size(); i++)
    {
        string CurStr = musicinfos[i];
        int Min = MinuteCalculation(CurStr.substr(0, 5), CurStr.substr(6, 5));
        string Title = "";
        string Score = "";
        bool IsFirst = false;
        for (size_t j = 12; j < CurStr.size(); j++)
        {
            char temp = CurStr[j];
            if (temp != ',' && IsFirst == false)
            {
                Title += temp;
            }
            else if (temp == ',')
            {
                IsFirst = true;
                continue;
            }
            else
            {
                Score += temp;
            }
        }

        string NewScore = ConvertSheetMusic(Score);
        string Music = CreateSheetMusic(Min, NewScore);

        if (Music.find(Newm) != -1)
        {
            if (Min > MaxPlayTime)
            {
                MaxPlayTime = Min;
                answer = Title;
            }
        }
    }

    return answer;
}

 

+ Recent posts