본문 바로가기

Algorithm

카카오 예비 코딩테스트 2번

2018년 8월 4일 카카오 코딩테스트 예선에 앞서서 예비 문제를 풀어보도록 하겠습니다.

이번에 풀어 볼 문제는 2번 단체사진 찍기 문제로 아래와 같습니다.






푸는 방식은 간단하면서도 살짝 어렵습니다.

기본적으로 8명의 카카오 프렌즈 친구들을 나열하는 문제이기 때문에 순열 문제로 접근할 수 있습니다.

예제 입력을 확인하자면 N~F=0은 N과 F가 나란히 (이웃하는) 서서 나열되는 경우입니다.

또한 R~T>2라는 것은 R과 T가 3이상 떨어져 있다는 것입니다.

이 두 조건을 만족하면서 8개의 알파벳을 나열하면 본 문제는 해결되는 것입니다.



따라서 알고리즘 회로를 생각해보면 아래와 같습니다.



1. 8개의 알파벳이 모두 나열될 때까지 Permutation 함수를 재귀로 돌립니다.

2. 8개의 알파벳이 모두 나열되어 하나의 문자열이 완성될 때 조건을 체크합니다.

3. 조건이 만족할 경우, 해당 문자열을 리스트에 넣어줍니다.

4. 조건에 만족하면서 이미 나열된 문자열을 담은 리스트의 사이즈를 반환합니다.




이 4개의 조건대로 코드를 정리하면 됩니다.


우선 Permutation 함수를 정의해보겠습니다.






private static void permutation(String str, int L, int F, String[] command) {


if (L == F) {

if (thePermuteCondition(str, command1) && thePermuteCondition(str, command2)) {

list.add(str);

}

} else {

for (int i = L; i <= F; i++) {


str = swap(str, L, i);

permutation(str, L + 1, F, command);

str = swap(str, L, i);  // back-tracking 

}

}

}




1번 조건을 코드 그대로 설명한 것입니다.

문자들을 나열하되, 8개의 문자들이 모두 나열되어 문자열이 될 수 있도록 하고,

그렇지 않을 경우는 계속해서 자리를 교환하며 문자들을 나열시킵니다. (재귀 방식) 



swap 함수는 아래와 같습니다.  보통의 swap함수와 같으며, 조금 신경써야 할 부분은

문자열을 받은 것이기 때문에 char형으로 바꿔서 변형 시켜줘야 한다는 점입니다.








private static String swap(String str, int i, int j) {

char temp;

char[] charArray = str.toCharArray();

temp = charArray[i];

charArray[i] = charArray[j];

charArray[j] = temp;

return String.valueOf(charArray);

}






다음은 입력으로 넣은 조건들을 체크할 함수를 만들어줍니다.

보통은 이러한 함수들은 boolean 형태로 만들어서 체크하도록 합니다.







private static boolean thePermuteCondition(String input, String command) {


// 같을 조건

if ((command.charAt(3) == '=')) {

if (Math.abs((input.indexOf(command.charAt(0)))

- input.indexOf(command.charAt(2))) == (Integer.parseInt(command.substring(4))) + 1) {


return true;

}

}


// 미만일 조건

if ((command.charAt(3) == '<')) {

if (Math.abs((input.indexOf(command.charAt(0))) - input.indexOf(command.charAt(2))) < (Integer

.parseInt(command.substring(4)))) {


return true;

}

}


// 초과일 조건

if ((command.charAt(3) == '>')) {

if (Math.abs((input.indexOf(command.charAt(0)))

- input.indexOf(command.charAt(2))) > (Integer.parseInt(command.substring(4))) + 1) {


return true;

}

}

return false;

}

}





입력으로 넣은 문자열에서 값들을 뽑아 내어 원래의 문자열의 인덱스를 찾아갑니다.

인덱스를 가지고 같을 경우, 초과일 경우, 미만일 경우로 나눠서 풀면 됩니다.

해당 조건이 만족할 경우 true를 반환하고 기본적으로는 false를 반환합니다.





이 조건을 가지고 8개의 알파벳이 모두 나열될 때 조건이 만족하는지 체크하면 됩니다.

이것이 3번 조건에 해당합니다.




전체 조건을 만족한 경우 리스트에 추가하여 최종적으로는

리스트의 사이즈를 반환하면 본 문제는 해결됩니다.

전체 코드는 다음과 같습니다.









package 카카오코딩테스트연습;


import java.util.ArrayList;

import java.util.Scanner;

import java.util.Stack;


public class 단체사진_찍기 {


private static Scanner scanner;

private static int n;

private static ArrayList<String> list;

private static Stack<String> commandStack;


public static void main(String[] args) {

// TODO Auto-generated method stub

scanner = new Scanner(System.in);

n = scanner.nextInt(); // 횟수


String[] command;

command = new String[n];

String kakaoFriends = "ACFJMNRT";

list = new ArrayList<>();

commandStack = new Stack<String>();


for (int k = 0; k < n; k++)

command[k] = scanner.next() + "";


permutation(kakaoFriends, 0, 7, command); 



// 문자열 index가 0부터 시작해서 7까지이기 때문..!! 


System.out.println(list.size());

}


private static String swap(String str, int i, int j) {

char temp;

char[] charArray = str.toCharArray();

temp = charArray[i];

charArray[i] = charArray[j];

charArray[j] = temp;

return String.valueOf(charArray);

}


private static void permutation(String str, int L, int F, String[] command) {

commandStack.push(command[0]);

String command1 = commandStack.pop();

commandStack.push(command[1]);

String command2 = commandStack.pop();

if (L == F) {

if (thePermuteCondition(str, command1) && thePermuteCondition(str, command2)) {

list.add(str);

}

} else {

for (int i = L; i <= F; i++) {


str = swap(str, L, i);

permutation(str, L + 1, F, command);

str = swap(str, L, i);  // Back-Tracking


}

}

}



private static boolean thePermuteCondition(String input, String command) {


// 같을 조건

if ((command.charAt(3) == '=')) {

if (Math.abs((input.indexOf(command.charAt(0)))

- input.indexOf(command.charAt(2))) == (Integer.parseInt(command.substring(4))) + 1) {


return true;

}

}


// 미만일 조건

if ((command.charAt(3) == '<')) {

if (Math.abs((input.indexOf(command.charAt(0))) - input.indexOf(command.charAt(2))) < (Integer

.parseInt(command.substring(4)))) {


return true;

}

}


// 초과일 조건

if ((command.charAt(3) == '>')) {

if (Math.abs((input.indexOf(command.charAt(0)))

- input.indexOf(command.charAt(2))) > (Integer.parseInt(command.substring(4))) + 1) {


return true;

}

}

return false;

}

}






감사합니다.





반응형

'Algorithm' 카테고리의 다른 글

기수변환 알고리즘  (0) 2018.11.14
백트래킹 코드 정리  (0) 2018.10.16
BOJ_11066_파일합치기  (0) 2018.07.29
팰린드롬 만들기  (0) 2018.07.27
BOJ_10942_팰린드롬?  (0) 2018.07.27