알고리즘/프로그래머스

프로그래머스 LV2. 단체사진 찍기 (자바)

reumiii 2022. 4. 19. 21:59

🍀 문제

입력 형식

입력은 조건의 개수를 나타내는 정수 n과 n개의 원소로 구성된 문자열 배열 data로 주어진다. data의 원소는 각 프렌즈가 원하는 조건이 N~F=0과 같은 형태의 문자열로 구성되어 있다. 제한조건은 아래와 같다.

  • 1 <= n <= 100
  • data의 원소는 다섯 글자로 구성된 문자열이다. 각 원소의 조건은 다음과 같다.
    • 첫 번째 글자와 세 번째 글자는 다음 8개 중 하나이다. {A, C, F, J, M, N, R, T} 각각 어피치, 콘, 프로도, 제이지, 무지, 네오, 라이언, 튜브를 의미한다. 첫 번째 글자는 조건을 제시한 프렌즈, 세 번째 글자는 상대방이다. 첫 번째 글자와 세 번째 글자는 항상 다르다.
    • 두 번째 글자는 항상 ~이다.
    • 네 번째 글자는 다음 3개 중 하나이다. {=, <, >} 각각 같음, 미만, 초과를 의미한다.
    • 다섯 번째 글자는 0 이상 6 이하의 정수의 문자형이며, 조건에 제시되는 간격을 의미한다. 이때 간격은 두 프렌즈 사이에 있는 다른 프렌즈의 수이다.

출력 형식

모든 조건을 만족하는 경우의 수를 리턴한다.

예제 입출력

n data answer
2 ["N~F=0", "R~T>2"] 3648
2 ["M~C<2", "C~M>1"] 0

예제에 대한 설명

첫 번째 예제는 문제에 설명된 바와 같이, 네오는 프로도와의 간격이 0이기를 원하고 라이언은 튜브와의 간격이 2보다 크기를 원하는 상황이다.

두 번째 예제는 무지가 콘과의 간격이 2보다 작기를 원하고, 반대로 콘은 무지와의 간격이 1보다 크기를 원하는 상황이다. 이는 동시에 만족할 수 없는 조건이므로 경우의 수는 0이다.

 

https://programmers.co.kr/learn/courses/30/lessons/1835

 

코딩테스트 연습 - 단체사진 찍기

단체사진 찍기 가을을 맞아 카카오프렌즈는 단체로 소풍을 떠났다. 즐거운 시간을 보내고 마지막에 단체사진을 찍기 위해 카메라 앞에 일렬로 나란히 섰다. 그런데 각자가 원하는 배치가 모두

programmers.co.kr

 

 

😊 나의 코드

class Solution {
    int answer = 0;

    public int solution(int n, String[] data) {
        char[] friends = { 'A', 'C', 'F', 'J', 'M', 'N', 'R', 'T' };
        boolean[] visited = new boolean[friends.length];
        perm(visited, "", data, friends);
        return answer;
    }

    public void perm(boolean[] visited, String way, String[] data, char[] friends) {
        if (way.length() == friends.length) {// 조건 맞는지 확인
            boolean check = true;
            for (int i = 0; check && i < data.length; i++) {
                char f1 = data[i].charAt(0);
                char f2 = data[i].charAt(2);
                int num = Character.getNumericValue(data[i].charAt(4));
                int gap = Math.abs(way.indexOf(f1) - way.indexOf(f2)) - 1;

                switch (data[i].charAt(3)) {
                case '=':
                    if (gap != num)
                        check = false;
                    break;
                case '>':
                    if (gap <= num)
                        check = false;
                    break;
                case '<':
                    if (gap >= num)
                        check = false;
                    break;
                }
            }

            if (check) {
                answer++;
            }
        } else {
            for (int i = 0; i < friends.length; i++) {
                if (!visited[i]) {
                    visited[i] = true;
                    perm(visited, way + friends[i], data, friends);
                    visited[i] = false;
                }
            }
        }
    }
}

 

순열로 모든 순서를 찾고 조건에 맞는 순서일 경우 answer에 1을 더해

만족하는 경우의 수인 answer를 리턴했다.