1. 문제 설명
영수가 숫자 3개를 머릿속으로 생각, 민혁이는 그 숫자를 맞추기 위해 3개의 수를 말하여 N번 추측을 한다.
민혁이가 말한 숫자 중 하나가 영수가 생각한 숫자와 위치도 같고, 숫자도 같으면 1 Strike,
민혁이가 말한 숫자 중 하나가 영수가 생각한 숫자와 위치는 다르지만, 숫자는 같으면 1ball,
이 행위를 N번 반복할 때, 영수가 생각한 숫자 3개가 될 수 있는 후보 수의 개수를 구하여라
2. 문제 푸는 원리
민혁이가 추측한 숫자가 영수의 머릿속 숫자와 얼마나 같은지는, 해당 숫자가 받은 ball_count를 보면 된다.
예시에서, 영수가 생각한 숫자가 324이고, 민혁이가 추측한 수가 429이면 1S 1B이다. 따라서 민혁이가 말한 숫자 N 개의 Ball_cnt를 모두 충족하는 수라면, 영수가 생각한 숫자가 될 수 있는 후보군으로서 자격을 충족한다.
문제 푸는 방법은 다음과 같다.
- 123 부터 789까지 모든 숫자를 확인한다. 현재 확인하는 수의 이름을 K라고 하자
(자릿수가 3개이므로 브루트포스로 풀리는 문제이다.) - K의 구성원으로 0이 들어있거나, 각 자릿수의 숫자가 같은 경우는 제외한다. (문제의 조건과 맞지 않다.)
- 스트라이크 수와 볼 수를 체크한다.
- 만약 K가 민혁이의 추측 수와 같으면 민혁이가 추측한 다음 수로 넘어간다.
만약 틀리면 K + 1한 수를 체크한다. - 만약 민혁이의 추측 수 N개 모두를 K가 통과하면, K는 영수의 머릿 속 숫자가 될 수 있는 자격이 있다.
따라서 candidate_cnt의 수를 하나 올린다.
3. 코드 분석
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
/*
* 숫자 야구 2503
* 1) 민혁이가 물어본 숫자와 볼 카운트가 일치하면, 어쩌면 3S가 가능한 숫자이다.
* 2) 민혁이가 물어본 숫자와 볼 카운트가 모두 일치하는 수의 개수를 센다.
* */
public class Main {
// ** 테스트 개수
static int N;
// ** Ball Count 배열, + 그 때의 값들 배열로 저장
static char [][] guess;
static int [] strike;
static int [] ball;
// ** 3S의 후보가 될 수 있는 값의 개수
static int candidate_cnt = 0;
static int [] now= new int[3];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 1) 값 입력 받기
N = Integer.parseInt(br.readLine());
guess = new char [N][3];
strike = new int[N];
ball = new int [N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
String s = st.nextToken();
// 1-1) 값 하나하나 분해해서 넣기
guess[i][0] = s.charAt(0);
guess[i][1] = s.charAt(1);
guess[i][2] = s.charAt(2);
// 1-2) 볼 카운트 넣기
strike[i] = Integer.parseInt(st.nextToken());
ball[i] = Integer.parseInt(st.nextToken());
}
// 2) 숫자 야구에서 나올 수 있는 모든 수를 가지고 Guess[j]와 비교하며 볼 카운트가 일치하면 다음 단계로 넘어가기.
// 아니면 Return 후 다음 껄로 다시 시도
next_num: for (int i = 123; i < 988; i++) {
String temp = String.valueOf(i);
// 0은 존재하지 않는 수이므로 유효성 바로 탈락
if(temp.charAt(0) == '0' || temp.charAt(1) == '0' || temp.charAt(2) == '0'){
continue ;
}
if( temp.charAt(0) == temp.charAt(1) || temp.charAt(0) == temp.charAt(2) || temp.charAt(1) == temp.charAt(2)){
continue;
}
// 2-1) 유효성 체크
for (int j = 0; j < N; j++) {
// a - 일치 확인
int strike_cnt = 0; int bal_cnt = 0;
// b - 민혁이가 추측한 값과 비교하여 해당 수의 총 스트라이크 볼 카운트 확인
outerLoop: for (int k = 0; k < 3; k++) {
// 스트라이크 확인 -> 두 수가 일치하면 바로 다음 수 체크
if(guess[j][k] == temp.charAt(k)){
strike_cnt++;
continue;
}
// 스트라이크가 아니라면 볼 카운트로는 맞는지 확인 -> ball 인게 확인되면 바로 다음 수 체크
for (int l = 0; l < 3; l++) {
if(guess[j][k] == temp.charAt(l) && k != l){
bal_cnt++;
continue outerLoop;
}
}
}
// 스트라이크 개수가 맞지 않으면 유효하지 않으므로 그 다음 수를 체크한다.
if(strike_cnt != strike[j]){
continue next_num;
}
// 볼 개수가 맞지 않으면 유효하지 않으므로 그 다음 수를 체크한다.
if(bal_cnt != ball[j]){
continue next_num;
}
}
// 2-2) 이 위치까지 Continue 거치지 않고 왔다는 것은 N개의 유효성 검증을 다 통과해낸 유효한 수라는 뜻이다.
candidate_cnt++;
}
System.out.println(candidate_cnt);
}
}
4. 소결
문제가 안 풀려서 답지를 봤다. 구현 능력이 많이 부족하다. 많이 풀어서 채워야겠다.
'알고리즘 > 문제 풀이' 카테고리의 다른 글
💜 백준 1038 감소하는 수 (0) | 2024.04.09 |
---|---|
💔 백준 14500 테트로미노 (0) | 2024.04.09 |
💚 5430 AC JAVA (0) | 2024.03.09 |
💔 14889. 스타트와 링크 (0) | 2024.03.08 |
💜 2589 보물섬 (0) | 2024.03.06 |