완전 탐색을 활용하는 문제이다. 이 문제에서의 완전탐색은 입력받은 질문한 세 자리 수를 비교하여 경우의 수를 찾는 문제가 아니라, 123부터 987까지 모든 값을 탐색하여 질문받은 값중에서 123~987의 값중 해당하지 않는 모든 값들을 지워나가는 방법을 사용해야한다.
중복된 숫자가 없다 하였으니 123~987중 중복된 숫자를 가지고 있다면 후보에서 제오한다. 1~9까지의 숫자로만 구성되어 있다 하였으므로 0이 들어갔다면 후보에서 제외한다.
다음은 질문을 통해 후보에서 제외할 경우를 찾는다. 123~987까지 탐색하면서 만약 후보로 가능한 값의 strike카운트와 ball카운트를 구했는데 입력받은 strike카운트와 ball카운트와 다르다면 후보에서 제외한다.
코드로는 이 부분이다.
if (arr[j]) {
for (int k{0}; k < 3; ++k) {
for (int l{0}; l < 3; ++l) {
if (k == l && tmp[k] == num[l]) ++sCnt;
if (k != l && tmp[k] == num[l]) ++bCnt;
}
}
if (sCnt != strike || bCnt != ball) arr[j] = false;
}
한 수를 잡고 입력 받은 수와 비교한다. 위치와 값이 같다면 ++strike 카운트
위치는 다르지만 값이 같다면 ++ball 카운트
입력받은 카운트와 구한 카운트가 다르다면 후보에서 제외
#include <iostream>
#include <string>
#include <algorithm>
bool arr[1'000];
int main() {
int N, strike, ball;
std::string num;
std::cin >> N;
std::fill(arr, arr + 1000, true);
for (int i{123}; i <= 987; ++i) {
std::string tmp = std::to_string(i);
if (tmp[0] == tmp[1] || tmp[1] == tmp[2] || tmp[0] == tmp[2]) arr[i] = false;
if (tmp[0] == '0' || tmp[1] == '0' || tmp[2] == '0') arr[i] = false;
}
for (int i{0}; i < N; ++i) {
std::cin >> num >> strike >> ball;
for (int j{123}; j <= 987; ++j) {
int sCnt{0}, bCnt{0};
std::string tmp = std::to_string(j);
if (arr[j]) {
for (int k{0}; k < 3; ++k) {
for (int l{0}; l < 3; ++l) {
if (k == l && tmp[k] == num[l]) ++sCnt;
if (k != l && tmp[k] == num[l]) ++bCnt;
}
}
if (sCnt != strike || bCnt != ball) arr[j] = false;
}
}
}
int cnt{0};
for (int i{123}; i <= 987; ++i) {
if (arr[i]) ++cnt;
}
std::cout << cnt;
return 0;
}