dev_beomgeun
꾸준하게 차근차근
dev_beomgeun
전체 방문자
오늘
어제
  • 분류 전체보기 (170)
    • 전공 (0)
      • 운영체제 (0)
      • 알고리즘 (0)
      • 자료구조 (0)
      • 데이터베이스 (0)
      • 네트워크 (0)
    • 개발 공부 (32)
      • 웹 (6)
      • 리눅스 (4)
      • 머신러닝 (1)
      • 스프링 (17)
      • Git (2)
      • AWS (2)
    • 개발 도서, 강의 (3)
      • 스프링 입문을 위한 자바 객체지향의 원리와 이해 (0)
      • 모든 개발자를 위한 HTTP 웹 기본 지식(김영한.. (2)
      • 스프링 부트와 AWS로 혼자 구현하는 웹서비스 (1)
    • 문제 풀이 (118)
      • 백준 알고리즘 (72)
      • 프로그래머스 알고리즘, SQL (38)
      • Hackerrank SQL (8)
    • 프로젝트 기록 (4)
      • 캡스톤 종합설계 (4)
      • 반려하루 프로젝트 (0)
    • 활동 기록 (12)
      • 네이버 부스트캠프 (7)
      • 취준 & 코테 (4)
      • 소프트웨어 마에스트로 13기 (1)
    • 이것저것 (1)

블로그 메뉴

  • 홈
  • 깃허브
  • 링크드인
  • 방명록

공지사항

인기 글

태그

  • 스프링
  • 부스트캠프
  • c++
  • 기록
  • HackerRank mysql
  • 일기
  • 서블릿
  • 반성
  • 백준
  • 프로그래머스 SQL
  • BFS
  • 그래프탐색
  • Hackerrank
  • 백준 DP
  • 네이버 부스트캠프
  • dp
  • 프로그래머스
  • 회고
  • AI Tech
  • Baekjoon

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
dev_beomgeun

꾸준하게 차근차근

문제 풀이/프로그래머스 알고리즘, SQL

[프로그래머스] 여행경로 (문자열, BFS) [C++]

2021. 3. 12. 23:24
728x90

programmers.co.kr/learn/courses/30/lessons/43164

 

코딩테스트 연습 - 여행경로

[["ICN", "SFO"], ["ICN", "ATL"], ["SFO", "ATL"], ["ATL", "ICN"], ["ATL","SFO"]] ["ICN", "ATL", "ICN", "SFO", "ATL", "SFO"]

programmers.co.kr

주어진 경로대로 탐색을 하면 되는데, 노드가 문자열이기도 하고 숫자로 매핑을 어떻게 해야 할지 몰라서 너무 복잡하게 풀었다.

 

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

using namespace std;

int check[10001][10001];
map<string, int> m;
vector<int> v[10001]; // int끼리 연결관계
vector<string> vs;
vector<string> answer;
int n;

bool compare(int& a, int& b) {
    return vs[a] < vs[b];
}

void DFS(int start) {
    answer.push_back(vs[start]);

    if (answer.size() == n + 1)
        return;

    for (int i = 0; i < v[start].size(); i++) {
        int next = v[start][i];
        if (check[start][next]) {
            check[start][next]--;
            DFS(next);
            if (answer.size() == n + 1)
                return;
            check[start][next]++;
            answer.pop_back();
        }
    }

}

vector<string> solution(vector<vector<string>> tickets) {
    n = tickets.size();
    int cnt = 1;
    m["ICN"] = 0;
    vs.push_back("ICN");
    for (int i = 0; i < tickets.size(); i++) {
        string from = tickets[i][0];
        string to = tickets[i][1];

        if (from != "ICN" && !m[from]) {
            m[from] = cnt;
            cnt++;
            vs.push_back(from);
        }
        if (to != "ICN" && !m[to]) {
            m[to] = cnt;
            cnt++;
            vs.push_back(to);
        }
        v[m[from]].push_back(m[to]);
        check[m[from]][m[to]]++;
    }

    for (int i = 0; i <= cnt; i++) {
        sort(v[i].begin(), v[i].end(), compare);
    }

    DFS(0);

    return answer;
}

코드를 설명하자면

1. map을 통해 각 경로 이름에 숫자를 매핑해주었다. (ICN부터 시작이니 0번을 넣어주었다.)

2. 티켓들을 순환하면서 새로 나오는 경로의 이름에 역시 숫자를 붙여주었다.

3. 그리고 그래프 순회를 하듯이 2차원 벡터에 매핑한 숫자들을 from, to로 해서 연결 정보를 저장했다.

4. 알파벳순으로 탐색을 해야 하므로 2차원 벡터들을 map의 문자열로 sort 해주었다.

5. DFS에서는 출발-도착의 탐색 여부를 탐색해주면서, 모든 티켓을 다 써야 한다는 조건 때문에 개수를 체크해주었다.

6. 만약 더 이상 갈 경로가 없지만 정답 개수가 티켓 하고 맞지 않다면 방문 여부를 해제해주면서 백 트래킹 해주었다.

7. 탐색 완료 & 개수가 일치하면 끝내주었다.

 

너무 복잡하다 ㅜㅜ

 

따라서 다른 분들의 코드를 참고해보았다.

 

#include <string>
#include <vector>
#include <algorithm>

using namespace std;
    vector<string> answer;
int DFS(string from, vector<vector<string>> & ticket, vector<bool> &visited, int depth){
    answer.push_back(from);
    if(depth == ticket.size()){
        return true;
    }
    
    for(int i = 0 ; i < ticket.size() ; i++){
        if(ticket[i][0] == from && !visited[i]){
            visited[i] = true;
            bool flag = DFS(ticket[i][1], ticket, visited, depth+1);
            if(flag){
                return true;
            }
            visited[i] = false;
        }
    }
    answer.pop_back();
    return false;
}



vector<string> solution(vector<vector<string>> tickets) {

    vector<bool> visited(tickets.size(), false);
    sort(tickets.begin(), tickets.end());
    DFS("ICN", tickets, visited, 0);

    return answer;
}

우선, 티켓 자체를 정렬해주어서 무조건 우선순위가 먼저인 티켓을 사용하게 해 주고

"ICN"부터 탐색을 시작해준다.

DFS에서는 티켓수만큼 사용해야 하므로 depth를 이용해주고, 티켓들을 순회하면서 만약 from이 일치하고 사용하지 않은 티켓이라면 사용해준다.

재귀를 이용해서 티켓을 다 사용하면 true, 아니면 false를 통해 방문을 해제해주고 정답에 넣은 경로도 빼주면서 진행을 해준다.

728x90
저작자표시 비영리 변경금지 (새창열림)

'문제 풀이 > 프로그래머스 알고리즘, SQL' 카테고리의 다른 글

[프로그래머스 LV3] 가장 먼 노드 (BFS) [C++]  (0) 2021.04.10
[프로그래머스 LV4] 3 x n 타일링 (DP) [C++]  (0) 2021.03.16
[프로그래머스] 등굣길 (DP, DFS) [C++]  (0) 2021.03.12
[프로그래머스 SQL] 입양 시각 구하기(2) group by, recursive  (0) 2021.02.26
[프로그래머스 SQL] DATETIME에서 DATE로 형 변환 (DATE, DATE_FORMAT)  (0) 2021.02.23
    '문제 풀이/프로그래머스 알고리즘, SQL' 카테고리의 다른 글
    • [프로그래머스 LV3] 가장 먼 노드 (BFS) [C++]
    • [프로그래머스 LV4] 3 x n 타일링 (DP) [C++]
    • [프로그래머스] 등굣길 (DP, DFS) [C++]
    • [프로그래머스 SQL] 입양 시각 구하기(2) group by, recursive
    dev_beomgeun
    dev_beomgeun
    백엔드 개발을 하며 얻은 지식과 경험을 공유합니다. 현재 카카오페이에서 백엔드 엔지니어로 일하고 있습니다.

    티스토리툴바