기록 보관소

[프로그래머스] 달리기 경주(C++) 본문

코딩 테스트/프로그래머스

[프로그래머스] 달리기 경주(C++)

JongHoon 2024. 9. 13. 20:30

프로그래머스 코딩 테스트 : Lv.1 문제(C++)

https://school.programmers.co.kr/learn/challenges?order=acceptance_desc&levels=1&languages=cpp&page=5

 

코딩테스트 연습 | 프로그래머스 스쿨

개발자 취업의 필수 관문 코딩테스트를 철저하게 연습하고 대비할 수 있는 문제를 총망라! 프로그래머스에서 선발한 문제로 유형을 파악하고 실력을 업그레이드해 보세요!

school.programmers.co.kr


프로그래머스 Lv.1 문제 : 달리기 경주

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제 설명

얀에서는 매년 달리기 경주가 열립니다.

해설진들은 선수들이 자기 바로 앞의 선수를 추월할 때 추월한 선수의 이름을 부릅니다.

예를 들어 1등부터 3등까지 "mumu", "soe", "poe" 선수들이 순서대로 달리고 있을 때, 해설진이 "soe"선수를 불렀다면 2등인 "soe" 선수가 1등인 "mumu" 선수를 추월했다는 것입니다.

즉 "soe" 선수가 1등, "mumu" 선수가 2등으로 바뀝니다.

선수들의 이름이 1등부터 현재 등수 순서대로 담긴 문자열 배열 players와 해설진이 부른 이름을 담은 문자열 배열 callings가 매개변수로 주어질 때, 경주가 끝났을 때 선수들의 이름을 1등부터 등수 순서대로 배열에 담아 return 하는 solution 함수를 완성해주세요.


제한사항

  • 5 ≤ players의 길이 ≤ 50,000
    • players[i]는 i번째 선수의 이름을 의미합니다.
    • players의 원소들은 알파벳 소문자로만 이루어져 있습니다.
    • players에는 중복된 값이 들어가 있지 않습니다.
    • 3 ≤ players[i]의 길이 ≤ 10
  • 2 ≤ callings의 길이 ≤ 1,000,000
    • callings는 players의 원소들로만 이루어져 있습니다.
    • 경주 진행중 1등인 선수의 이름은 불리지 않습니다.

입출력 예

입출력 예
입출력 예 설명


코드

#include <string>
#include <vector>
#include <map>

using namespace std;

vector<string> solution(vector<string> players, vector<string> callings) {
    map<int, string> m1;
    map<string, int> m2;
    vector<string> answer;
    
    for (int i = 0; i < players.size(); i++) {
        m1[i] = players[i];
        m2[players[i]] = i;
    }
    
    for (auto calling : callings) {
        string temp_name = m1[m2[calling] - 1];
        int temp_rank = m2[calling];
        
        m1[m2[calling] - 1] = calling;
        m1[m2[calling]] = temp_name;
        m2[calling] = temp_rank - 1;
        m2[temp_name] = temp_rank;
    }
    
    for (auto it : m1)
        answer.push_back(it.second);
    
    return answer;
}
// 다른 사람의 풀이 : map과 player를 수정해서 해결하는 방법

#include <map>
#include <string>
#include <vector>
#include <iostream>

using namespace std;

vector<string> solution(vector<string> players, vector<string> callings)
{
    vector<string> answer;

    map<string, int> m;
    for(int i=0; i<players.size(); i++)
        m[players[i]]=i;


    int s1, s2;
    string tmp;
    for(int i=0; i<callings.size(); i++)
    {
        s2=m[callings[i]]; s1=s2-1;
        m[players[s2]]--; m[players[s1]]++;
        //cout << s1 << " " << s2 << endl;
        tmp=players[s2];
        players[s2]=players[s1];
        players[s1]=tmp;
    }

    answer=players;

    return answer;
}

결과


여담

고정된 값을 계속 변경하면 되는 문제라 맵을 쓰면 될 것 같아서 string을 key로 int를 value로 하는 맵으로 시도 했는데, 나는 중간에 value로 key를 찾는 iterator를 써서 시간 초과로 아쉽게 실패했었다.

그 뒤에 바로 서로 키 값이 반대로 된 맵을 2개로 해서 계속 업데이트 해나간다면 iterator를 쓰지 않아 더 빠르게 해결될 것 같아서 2개의 맵을 만들었고 예상대로 해결할 수 있었다.

다만 2개의 맵을 계속 서로의 값을 끌어와서 바꾸다보니 중간에 조금 헷갈려서 고생 좀 했었다ㅋㅋ

다른 사람의 풀이처럼 player를 쓰면 훨씬 더 깔끔하고 직관적으로 해결할 수 있었을텐데~ 하는 아쉬움은 조금 있다.