티스토리 뷰

반응형

 

카카오 프렌즈들이 단체사진을 찍으려 하는데 각자 원하는 조건이 있다. 

프렌즈들이 원하는 조건에 맞춰 단체사진을 찍을 수 있는 경우의 수를 구하는 문제

 


문제의 조건

 

1. 프렌즈들이 원하는 조건의 갯수 n, n만큼 조건을 담은 string 배열 data가 주어진다. 

 

2. data의 각 원소는 "N~F=0" 과 같이 주어지는데

N(네오)는 F(프로도)와 0칸 떨어져 있고 싶다는 뜻이다. 

즉 바로 옆에 붙어있고 싶다는 뜻이므로 둘 사이의 거리는 1이어야 한다는 뜻이 된다. (겹쳐있진 않고 일렬로 서 있으니까)

그렇다면 실제로 계산에 사용해야 할 프렌즈 사이의 거리는 주어지는 수에서 +1 한 값이라는 말이 된다. 

"N~F>1" 이라면 1칸을 초과해서 떨어져 있고 싶다는 뜻이고

"N~F<2" 라면 2칸 미만으로 떨어져 있고싶다 라는 뜻이다. 

 

3. n개의 조건을 모두 만족하는 경우의 수를 구해야 하기 때문에 

모든 프렌즈들을 나열할 수 있는 순열을 만들어본 후 거기에서 모든 조건을 만족하는 프렌즈 조합을 정답에 포함시켜야 한다. 

조합이 아닌 순열을 쓰는 이유는

조합에는 순서가 없지만 순열에는 순서가 있기 때문이다. 

순서가 왜 중요하냐면 위치에 따라 사진 자체가 달라지니깐... 이라고 생각했다. 

 


그래서 구현한 로직은

모든 프렌즈를 나열한 문자열의 순열을 만들면서 만들 때마다 주어진 조건과 비교해 answer를 증가시키는 방식으로 했다. 

 

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

using namespace std;

// 전역 변수를 정의할 경우 함수 내에 초기화 코드를 꼭 작성해주세요.
int solution(int n, vector<string> data) {
    int answer = 0;
    string friends = "ACFJMNRT";
    do //next_permutation을 이용해 순열을 만들기위한 반복문 
    {
        bool isRight = false;
        for (int i = 0; n > i; i++)
        {
            //새로운 순열이 만들어질 때마다 순열 속에서 조건이 있는 프렌즈들의 위치를 찾는다.
            auto first = find(friends.begin(), friends.end(), data[i][0]);
            auto another = find(friends.begin(), friends.end(), data[i][2]);
            
            //두 반복자 사이의 거리를 구한다. 
            //거리를 구할 땐 abs를 써서 꼭 절대값으로 구하는 것을 잊지 말자...!!(내가 잊었음)
            int dist = abs(distance(first, another));
            
            //조건문에 data[i][3]으로 바로 쓰니까 헷갈려서 연산자 저장할 변수 따로 만듦
            char oper = data[i][3];
            
            //떨어져 있길 바라는 거리를 구해야 하는데 주어지는 매개변수가 string이라 
            //숫자가 char형으로 저장되어 있음
            //char형 숫자는 0이 아닌 아스키 코드로 저장되어 있기 때문에 
            //아스키 코드 상에서 숫자의 시작인 '0'을 빼 줘야 찐 숫자가 된다. 
            //그리고 프렌즈간 최소 거리가 1이기 때문에 1 더해주기 
            int condition = data[i][4] - '0' + 1;

            //연산자별로 조건을 비교해서 조건에 맞으면 검사를 계속 진행하고
            //맞지 않으면 bool 변수를 false로 바꾸고 검사를 즉시 중단한다. 
            if ('=' == oper)
            {
                if (condition == dist)
                    isRight = true;
                else 
                {
                    isRight = false;
                    break;
                }
            }
            else if ('<' == oper)
            {
                if (condition > dist)
                    isRight = true;
                else
                {
                    isRight = false;
                    break;
                }
            }
            else if ('>' == oper)
            {
                if (condition < dist)
                    isRight = true;
                else
                {
                    isRight = false;
                    break;
                }
            }
        }

        //조건을 하나라도 충족하지 않으면 bool 변수를 false로 바꾸고 즉시 검사를 종료하기 때문에
        //모든 조건을 충족한다면 bool 변수는 true일 것이다. 
        if (isRight)
            answer++;
    } while (next_permutation(friends.begin(), friends.end()));

    return answer;
}

 

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함