본문 바로가기

알고리즘(Algorithm)

[C++] 숫자 야구 (2503번)

숫자 야구

 
 
시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초 128 MB 15362 7258 5852 47.216%

문제

정보문화진흥원 정보 영재 동아리에서 동아리 활동을 하던 영수와 민혁이는 쉬는 시간을 틈타 숫자야구 게임을 하기로 했다.

  • 영수는 1에서 9까지의 서로 다른 숫자 세 개로 구성된 세 자리 수를 마음속으로 생각한다. (예: 324)
  • 민혁이는 1에서 9까지의 서로 다른 숫자 세 개로 구성된 세 자리 수를 영수에게 묻는다. (예: 123)
  • 민혁이가 말한 세 자리 수에 있는 숫자들 중 하나가 영수의 세 자리 수의 동일한 자리에 위치하면 스트라이크 한 번으로 센다. 숫자가 영수의 세 자리 수에 있긴 하나 다른 자리에 위치하면 볼 한 번으로 센다.

예) 영수가 324를 갖고 있으면 

  • 429는 1 스트라이크 1 볼이다.
  • 241은 0 스트라이크 2 볼이다.
  • 924는 2 스트라이크 0 볼이다.
  • 영수는 민혁이가 말한 수가 몇 스트라이크 몇 볼인지를 답해준다.
  • 민혁이가 영수의 세 자리 수를 정확하게 맞추어 3 스트라이크가 되면 게임이 끝난다. 아니라면 민혁이는 새로운 수를 생각해 다시 영수에게 묻는다.

현재 민혁이와 영수는 게임을 하고 있는 도중에 있다. 민혁이가 영수에게 어떤 수들을 물어보았는지, 그리고 각각의 물음에 영수가 어떤 대답을 했는지가 입력으로 주어진다. 이 입력을 바탕으로 여러분은 영수가 생각하고 있을 가능성이 있는 수가 총 몇 개인지를 알아맞혀야 한다.

아래와 같은 경우를 생각해보자.  

  • 민혁: 123
  • 영수: 1 스트라이크 1 볼.
  • 민혁: 356
  • 영수: 1 스트라이크 0 볼.
  • 민혁: 327
  • 영수: 2 스트라이크 0 볼.
  • 민혁: 489
  • 영수: 0 스트라이크 1 볼.

이때 가능한 답은 324와 328, 이렇게 두 가지이다.

영수는 동아리의 규율을 잘 따르는 착한 아이라 민혁이의 물음에 곧이곧대로 정직하게 답한다. 그러므로 영수의 답들에는 모순이 없다.

민혁이의 물음들과 각각의 물음에 대한 영수의 답이 입력으로 주어질 때 영수가 생각하고 있을 가능성이 있는 답의 총 개수를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트라이크 개수를 나타내는 정수와 볼의 개수를 나타내는 정수, 이렇게 총 세 개의 정수가 빈칸을 사이에 두고 주어진다.

출력

첫 줄에 영수가 생각하고 있을 가능성이 있는 답의 총 개수를 출력한다.


문제풀이

 

접근 방법이 도저히 생각나지 않아 풀이 방법을 찾아봤다. 조건 분기를 해서 풀려고 생각했는데 너무 복잡하다고 생각했다. n이 별로 크지 않길래 완전탐색 방법도 생각해 봤지만 도저히 어떻게 해야할지 감이 잡히지 않았다. 다른 사람들의 풀이를 보고 이걸 어떻게 생각했지 라는 생각을 했다.

완전탐색을 하는 것이 맞는데, 123 ~ 987 각각의 값이 주어진 스트라이크, 볼에 부합하는지 하나하나 확인해주면 간단하게 답을 구할 수 있다.

kt 코딩테스트에서 이와 비슷한 문제를 봤던 기억이 있는데 그때 풀지 못했다. 이 문제를 코테 전에 풀어봤더라면,, 그 문제는 맞았을 건데 후회가 많이 남는다.

예를 들어 123의 경우를 예제 입력 1과 비교해본다면, 처음 123과 비교해보면 3s이므로 1s 1b과 값이 다르기 때문에 123은 가능성이 있는 답이 아니다. 이런식으로 모두 확인해보면 개수를 구할 수 있다. 경우의 수는 간략하게 계산해보면 123 

~ 987 까지 중복되는 값은 빼야하지만 대충  900 이라치고, 입력받는 개수가 100이므로 90000정도의 반복을 돌면 해결되기 때문에 시간복잡도는 염려할 필요가 없다.

 

#include <iostream>
#include <string>

using namespace std;

int strike[100], ball[100];
string numbers[100];

int main() {
    int n;
    cin >> n;
    for(int i=0; i<n; i++) {
        string s;
        int q, w;
        cin >> s >> q >> w;
        numbers[i] = s;
        strike[i] = q;
        ball[i] = w;
    }
    int answer = 0;
    for(int i=1; i<=9; i++) {
        char a = i + '0';
        for(int j=1; j<=9; j++) {
            char b = j + '0';
            if(a == b) continue;
            for(int k=1; k<=9; k++) {
                char c = k + '0';
                if(a == c || b == c) continue;
                bool check = true;
                for(int l=0; l<n; l++) {
                    int st = 0, ba = 0;
                    if(a == numbers[l][0]) st++;
                    if(b == numbers[l][1]) st++;
                    if(c == numbers[l][2]) st++;
                    if(a == numbers[l][1] || a == numbers[l][2]) ba++;
                    if(b == numbers[l][0] || b == numbers[l][2]) ba++;
                    if(c == numbers[l][0] || c == numbers[l][1]) ba++;
                    if(strike[l] != st || ball[l] != ba) {
                        check = false;
                        break;
                    }
                }
                if(check) answer++;
            }
        }
    }
    cout << answer;

    return 0;
}

'알고리즘(Algorithm)' 카테고리의 다른 글

[C++] 빗물 (14719번)  (0) 2023.06.13
[C++] 미세먼지 안녕! (17144번)  (3) 2023.06.02
[C++] 동전 1 (2293번)  (0) 2023.05.09
[C++] 스도쿠 (2580번)  (0) 2023.05.02
[C++] 후보 추천하기 (1713번)  (0) 2023.04.28