Programmers : https://programmers.co.kr/learn/courses/30/lessons/42841

 

코딩테스트 연습 - 숫자 야구

[[123, 1, 1], [356, 1, 0], [327, 2, 0], [489, 0, 1]] 2

programmers.co.kr

 

숫자 야구 게임이란 2명이 서로가 생각한 숫자를 맞추는 게임입니다.

각자 서로 다른 1~9까지 3자리 임의의 숫자를 정한 뒤 서로에게 3자리의 숫자를 불러서 결과를 확인합니다.

그리고 그 결과를 토대로 상대가 정한 숫자를 예상한 뒤 맞힙니다.

* 숫자는 맞지만, 위치가 틀렸을 때는 볼

* 숫자와 위치가 모두 맞을 때는 스트라이크

* 숫자와 위치가 모두 틀렸을 때는 아웃

 

예를 들어, 아래의 경우가 있으면

A : 123 B : 1스트라이크 1볼.

A : 356 B : 1스트라이크 0볼.

A : 327 B : 2스트라이크 0볼.

A : 489 B : 0스트라이크 1볼.

이때 가능한 답은 324와 328 두 가지입니다.

 

질문한 세 자리의 수, 스트라이크의 수, 볼의 수를 담은 2차원 배열 baseball이 매개변수로 주어질 때,

가능한 답의 개수를 return 하도록 solution 함수를 작성해주세요.

 

programmers level2 숫자 야구 문제입니다.

 

숫자를 사용하는 범위가 매우 작기 때문에 모든 경우의 수를 고려해도 괜찮은 완전 탐색류에 해당하는 문제입니다.

 

가장 먼저, 비교해줄 수 있는 모든 숫자를 표현해주시고

현재 받은 숫자와 모든 숫자를 전부 비교해서 가능한 숫자만 추려내주시면 됩니다.

 

설명은 주석을 달아놓았으니, 보시면 이해되실 겁니다.

#include <string>
#include <vector>

using namespace std;

bool check_baseball(int k, int num, int s, int b) { // 두 숫자의 strike, ball을 판단
    int ss = 0, bb = 0;

    // 간편한 비교를 위해서 스트링을 사용했습니다.
    string kk = to_string(k);
    string numnum = to_string(num);

    for (int i = 0; i < 3; i++) {
        for (int k = 0; k < 3; k++) {
            // 만약 두 숫자가 같다면
            if (kk[i] == numnum[k]) {
                if (i == k) ss++; // 같은 인덱스인 경우 strike!
                else bb++; // 아닌 경우 ball!
            }
        }
    }

    if (s == ss && b == bb) return true; // 비교를 통해 가능한 숫자인지 판단해줍니다
    else return false;
}

int solution(vector<vector<int>> baseball) {
    int answer = 0;

    bool can_num[1000]; // 가능한 모든 숫자!
    for (int i = 0; i < 1000; i++) can_num[i] = false; // 일단 모두 사용 불가능으로 초기화했습니다.

    // 1~9까지 3자리 수를 만드는데
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= 9; j++) {
            for (int k = 1; k <= 9; k++) {
                // 서로 중복되는 경우는 없기 때문에 다음과 같은 조건을 줍니다
                if (i == j || i == k || j == k) continue;
                // 조건에 부합하지 않는다면 이 수는 사용가능한 숫자겠네요!
                can_num[i * 100 + j * 10 + k] = true;
            }
        }
    }

    for (int i = 0; i < baseball.size(); i++) {
        // 질문을 가지고 와서
        int num = baseball[i][0];
        int s = baseball[i][1];
        int b = baseball[i][2];

        for (int k = 111; k < 1000; k++)
            // 만약 현재 숫자가 비교가능한 숫자면 check_baseball 함수를 통해 비교해줍니다
            if (can_num[k]) can_num[k] = check_baseball(k, num, s, b);
    }

    for (int i = 111; i < 1000; i++) if (can_num[i]) answer++; // true인 모든 숫자가 경우의 수가 됩니다.

    return answer;
}

'algorithm > programmers' 카테고리의 다른 글

Programmers 디스크 컨트롤러 C++  (0) 2020.08.20
Programmers 카펫 C++  (0) 2020.07.03
Programmers 소수 찾기 C++  (0) 2020.07.03
Programmers 라면공장(C++)  (0) 2020.07.02
programmers N으로 표현  (0) 2020.03.12

+ Recent posts