알고리즘/프로그래머스 2단계

프로그래머스 - 스킬트리 - C++

게임만드는학생 2024. 8. 6. 12:52

https://school.programmers.co.kr/learn/courses/30/lessons/49993#fnref1

 

프로그래머스

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

programmers.co.kr

 

#include <string>
#include <vector>

using namespace std;

int solution(string skill, vector<string> skill_trees) {
    int answer = 0;
    
    for(auto& str : skill_trees)
    {
        vector<int> arr(26,0);
        for(int i=0;i<skill.length();i++)
            arr[skill[i]-65]=-1;

        int IdPointer=0;
        arr[skill[IdPointer]-65]=1;
        bool b=true;
        for(auto& c : str)
        {
            if(arr[c-65]==0||arr[c-65]==2)continue;
            else if(arr[c-65]==1)
            {
                arr[c-65]=2;
                IdPointer++;
                if(IdPointer<skill.length())
                    arr[skill[IdPointer]-65]=1;
            }
            else if(arr[c-65]==-1)
            {
                b=false;break;
            }
                
        }
        if(b)answer++;
    }
    
    return answer;
}

 

이 문제는 문자열을 보면서 해당스킬을 찍을 수 있는지 확인하는 것이다. 

선행 스킬이 있다면 그 스킬을 찍어야 다음스킬을 찍을 수 있는데 그것을 어떻게 확인할지가 문제였다. 

 

arr벡터를 만들어 각 스킬별로 상태를 표시하였다. 

-1 = 찍을 수 없는 스킬, 0 = 상관없는 스킬, 1 = 찍을 수 있는 스킬, 2 = 찍은 스킬

 

그리고 skill 문자열에서 현재 어느 스킬까지 찍었는지를 확인할 포인터로 IdPointer를 만들었다. 

 

skill[IdPointer]-65 가 0이라면 A를 뜻한다. 

arr[0] (=arr[A]) 가 만약 1이라면 찍을 수 있는 스킬이다. 

 

이런식으로 표시하여 skill_trees의 각 원소별로 체크한다. 

 

1. 상태를 초기화한다. 

2. 각 스킬별로 어떤상태인지 확인한다. 

 2-1. 0,2 면 패스 (선행이 없거나 이미 찍은스킬)

 2-2. 1이면 찍을 수 있는 스킬로 이 스킬을 찍으면 다음 스킬이 열린다. 따라서 idPointer를 1증가시킨다.

 2-3. 만약 -1 이라면 못찍는 스킬이므로 거기서 반복문을 종료한다. 

3. 만약 가능한 스킬트리면 answer를 1 증가시킨다. 

 

이런식으로 모든 원소를 순회한다.