Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • 프로그래머스
  • Kubernetes
  • 백트래킹
  • docker
  • 다이나믹 프로그래밍
  • boj
  • Network
  • django
  • BFS
  • DFS

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

[프로그래머스] level2 단체사진 찍기 (C++)
Algorithm/프로그래머스

[프로그래머스] level2 단체사진 찍기 (C++)

2022. 1. 18. 05:01

2017 카카오코드 본선

 

 

사람이 8명 뿐이다.

모든 사람을 줄세우는데 O(8!) 만큼의 시간이 걸릴 것이다.

따라서 백트래킹으로 모든 경우를 탐색해도 시간내에 충분히 풀린다.

 

 

백트래킹 부분

void sorting(int cnt, int &answer, vector<string> &data, map<char, int> &m){
    if(cnt == 8){
        if(is_valid(data, m)){
            answer++;
        }
        return;
    }
    
    for(int i = 0; i < 8; i++){
        if(visited[i]) continue;
        visited[i] = cnt+1;
        sorting(cnt+1, answer, data, m);
        visited[i] = 0;
    }
}

중요한 부분은 visited배열의 정의이다.

 

visited배열의 인덱스는 사람의 번호이다. 이때 값으로 인덱스에 해당하는 번호의 사람이 줄의 몇 번째에 들어갔는지가 들어간다.

cnt가 줄의 몇 번째인지를 나타낸다.

 

cnt가 8이 되어서 현재 줄을 선 모양새가 문제에서 요구하는 조건에 일치한다면 답을 +1 증가시킨다.

 

 

줄 선 모양새 판별

bool is_valid(vector<string> &data, map<char, int> &m){
    for(int i = 0; i < data.size(); i++){
        int target1 = visited[m[data[i][0]]];
        int target2 = visited[m[data[i][2]]];
        char op = data[i][3];
        int xop = data[i][4] - '0';
        
        if(op == '='){
            if(abs(target1 - target2) == xop + 1) continue;
            else return false;
        }
        else if(op == '>'){
            if(abs(target1 - target2) > xop + 1) continue;
            else return false;
        }
        else if(op == '<'){
            if(abs(target1 - target2) < xop + 1) continue;
            else return false;
        }
    }
    
    return true;
}

위 코드에는 안나와있지만 map 자료구조를 사용해서 사람의 이름(A, C, F, J ...)에 맞게 사람의 id 값을 저장해 놓았다.

 

int target1 = visited[m[data[i][0]]];
int target2 = visited[m[data[i][2]]];

data[i][0]과 data[i][2]는 문제에서 주어진 조건에 나오는 사람이다.

m[data[i][0]]을 해주면 그 사람의 id를 알 수 있다.

m[data[i][0]]를 id라고 하겠다.

 

visited[id]를 해주면 해당 id인 사람이 몇 번째로 줄을 섰는지 알 수 있다!

이제 문제는 거의 다 풀었다.

 

연산자에 맞게 조건이 맞는지를 확인해주면 된다.

 

 

 

최종 코드

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

using namespace std;


// char kakao[9] = {'A', 'C', 'F', 'J', 'M', 'N', 'R', 'T'};
int visited[9];

void map_insert(map<char, int> &m){
    m.insert({'A', 0});
    m.insert({'C', 1});
    m.insert({'F', 2});
    m.insert({'J', 3});
    m.insert({'M', 4});
    m.insert({'N', 5});
    m.insert({'R', 6});
    m.insert({'T', 7});
}

bool is_valid(vector<string> &data, map<char, int> &m){
    for(int i = 0; i < data.size(); i++){
        int target1 = visited[m[data[i][0]]];
        int target2 = visited[m[data[i][2]]];
        char op = data[i][3];
        int xop = data[i][4] - '0';
        
        if(op == '='){
            if(abs(target1 - target2) == xop + 1) continue;
            else return false;
        }
        else if(op == '>'){
            if(abs(target1 - target2) > xop + 1) continue;
            else return false;
        }
        else if(op == '<'){
            if(abs(target1 - target2) < xop + 1) continue;
            else return false;
        }
    }
    
    return true;
}

void sorting(int cnt, int &answer, vector<string> &data, map<char, int> &m){
    if(cnt == 8){
        if(is_valid(data, m)){
            answer++;
        }
        return;
    }
    
    for(int i = 0; i < 8; i++){
        if(visited[i]) continue;
        visited[i] = cnt+1;
        sorting(cnt+1, answer, data, m);
        visited[i] = 0;
    }
}

// 전역 변수를 정의할 경우 함수 내에 초기화 코드를 꼭 작성해주세요.
int solution(int n, vector<string> data) {
    memset(visited, 0, sizeof(visited));
    int answer = 0;
    map<char, int> m;
    map_insert(m);
    
    sorting(0, answer, data, m);
    
    return answer;
}

'Algorithm > 프로그래머스' 카테고리의 다른 글

[프로그래머스] level2 순위 검색 (Python)  (0) 2022.01.26
[프로그래머스] level2 전화번호 목록 (C++)  (0) 2022.01.18
[프로그래머스] level2 빛의 경로 사이클 (C++)  (0) 2022.01.18
[프로그래머스] level2 튜플 (C++)  (0) 2022.01.18
[프로그래머스] level2 행렬 테두리 회전하기 (C++)  (0) 2022.01.16
    'Algorithm/프로그래머스' 카테고리의 다른 글
    • [프로그래머스] level2 순위 검색 (Python)
    • [프로그래머스] level2 전화번호 목록 (C++)
    • [프로그래머스] level2 빛의 경로 사이클 (C++)
    • [프로그래머스] level2 튜플 (C++)

    티스토리툴바