알고리즘
[프로그래머스] 비밀 코드 해독 - Java
2won2
2025. 7. 22. 16:31
비밀 코드 해독 (Lv2)
https://school.programmers.co.kr/learn/courses/30/lessons/388352
코딩테스트 연습 - 비밀 코드 해독
알고리즘 문제 연습 카카오톡 친구해요! 프로그래머스 교육 카카오 채널을 만들었어요. 여기를 눌러, 친구 추가를 해주세요. 신규 교육 과정 소식은 물론 다양한 이벤트 소식을 가장 먼저 알려
school.programmers.co.kr
제한 사항
- 10 ≤ n ≤ 30
- 1 ≤ (q의 길이 = m) ≤ 10
- q[i]의 길이 = 5
- q[i]는 i+1번째 시도에서 입력한 5개의 서로 다른 정수를 담고 있으며, 오름차순으로 정렬되어 있습니다.
- 1 ≤ q[i][j] ≤ n
- ans의 길이 = m
- ans[i]는 i+1번째 시도에서 입력한 5개의 정수 중 비밀 코드에 포함된 정수의 개수를 나타냅니다.
- 0 ≤ ans[i] ≤ 5
- 비밀 코드가 존재하지 않는(답이 0인) 경우는 주어지지 않습니다.
풀이
이번 문제는 조합을 이용해서 풀었다.
먼저 문제에서 비밀코드는 5자리라고 했으므로 1부터 n까지 숫자 중 5개를 조합해서 만든다.
이는 n이 최대 30인 경우에도 142506번 밖에 걸리지 않는다.
다음으로 만들어진 조합이 정답이라고 가정한 후 q 배열 전부와 비교를 한다.
이때, q 배열과 일치하는 것이 x개인데 ans[q인덱스]가 y개(x!=y)라면 맞지 않는 것이다.
예를 들어, 조합이 [1,2,3,4,5], q[0] = [1,2,3,4,6], ans[qIdx] = 3인 경우에, 조합이 정답이라고 가정했기에 q[0]과의 교집합은 4가 나와야 한다. 하지만 ans[qIdx] = 3이므로 [1,2,3,4,5]는 정답이 될 수 없다.
이처럼 모든 조합에 대해 비교한 후, 모든 조건에 부합한다면 answer를 하나 늘려 정답을 구했다.
전체 Code
class Solution {
int[] sub;
int answer;
public int solution(int n, int[][] q, int[] ans) {
answer = 0;
sub = new int[5];
comb(0,1,n,q,ans);
return answer;
}
private void comb(int idx, int num, int n, int[][] q, int[] ans){
if(idx==5){
if(calculate(q,ans)) answer++;
return;
}
for(int i=num; i<=n; i++){
sub[idx] = i;
comb(idx+1, i+1, n, q, ans);
}
}
private boolean calculate(int[][] q, int[] ans){
int[] subCnt = new int[31];
for(int s : sub){
subCnt[s]++;
}
for(int i=0; i<q.length; i++){
int cnt = 0;
// q를 순회하면서 같은게 몇개 있는지 판별
for(int j=0; j<q[i].length; j++){
if(subCnt[q[i][j]]==1) cnt++;
}
// 같은게 3개다. 근데 ans는 2개다? 같은게 2개다. 근데 ans는 3개다? 다 말이 안된다.
if(cnt != ans[i]) return false;
}
return true;
}
}