https://www.acmicpc.net/problem/2503
import java.util.*;
import java.io.*;
class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
List<Query> querys = new ArrayList<>();
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int answer = Integer.parseInt(st.nextToken());
int strike = Integer.parseInt(st.nextToken());
int ball = Integer.parseInt(st.nextToken());
querys.add(new Query(answer, strike, ball));
}
int result = 0;
for (int num = 123; num < 988; num++) {
if (!isValid(num)) {
continue;
}
int correctCount = 0;
for (Query query : querys) {
int strikeCount = 0;
int ballCount = 0;
String numStr = Integer.toString(query.answer);
String targetStr = Integer.toString(num);
// 스트라이크 검사
for (int i = 0; i < 3; i++) {
if (numStr.charAt(i) == targetStr.charAt(i)) {
strikeCount++;
}
}
if (strikeCount != query.strike) {
break;
}
// 볼 검사
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (numStr.charAt(i) == targetStr.charAt(j) && (i != j)) {
ballCount++;
}
}
}
if (ballCount != query.ball) {
break;
}
if (strikeCount == query.strike && ballCount == query.ball) {
correctCount++;
}
}
if (correctCount == N) {
result++;
}
}
System.out.println(result);
}
static boolean isValid(int num) {
int first = num / 100;
int second = num % 100 / 10;
int third = num % 10;
if (second == 0 || third == 0) {
return false;
}
if (first == second || second == third || first == third) {
return false;
}
return true;
}
static class Query {
int answer;
int strike;
int ball;
Query(int answer, int strike, int ball) {
this.answer = answer;
this.strike = strike;
this.ball = ball;
}
}
}
스트라이크
또는 볼
의 개수로 상대방이 생각한 수를 유추하는 것이 목적이라면, 이 문제는 특이하게 상대방이 생각할 가능성이 있는 수의 개수를 구하는 것이었다.물어본 숫자
, 스트라이크의 개수
, 볼의 개수
가 순차적으로 한 줄에 주어진다.123
, 1
, 2
라는 입력이 주어졌을 때 123
이라는 숫자에 대해서 스트라이크 1개와 볼 2개가 될 수 있는 모든 숫자를 의미한다.Query
라는 객체 리스트에 저장한다. 그 후 123 ~ 987
에 존재하는 숫자들에 대해서 query
를 모두 만족하는 수들을 구한다.1) 서로 겹치면 안되며(ex 112)
2) 0이 들어가면 안된다. (120)
123
, 1
, 2
라는 입력에 대해서 132
라는 값은 1스트라이트 2볼이라는 조건에 부합한다.strike
의 경우는 num.charAt(i)
과 target.charAt(i)
가 만족하는 경우를 의미한다.ball
의 경우는 수가 안에 존재하지만, 자리는 다른 경우를 의미한다. 따라서 이중for문을 사용하며 num.charAt(i) == target.charAt(j)
이면서 i != j
인 경우가를 의미한다.result
를 1증가시킨다.브루트포스
로도 충분히 선형의 시간복잡도로 해결할 수 있다.