코딩테스트 준비/백준

[백준 2503] - 숫자 야구(구현) C++

SeoburiFaust 2024. 3. 21. 18:37

문제

https://www.acmicpc.net/problem/2503

 

2503번: 숫자 야구

첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트

www.acmicpc.net

접근방법

경우의 수를 줄여나간다는 생각은 했는데, 줄여나가는 방법에서 미스가 많았다.

10*10*10의 배열에 true false로 경우의 수를 체크했는데 이는 좋은 방법이 아니었다.

123부터 시작해서 987까지 1차원 배열에 담은 후에 숫자를 꺼내서, to_string을 이용해 각 자리의 수를 확인할 수 있는 방법이 있었다.

 

아쉽게도 이 방법을 생각하지 못했던게 패인인 거 같다.

 

to_string으로 숫자를 문자열로 만들어줬다면, 123부터 987까지 모든 숫자와 비교해 strike와 ball의 조건과 맞지 않는 숫자를 찾아 false로 만들어주면 된다.

 

코드

#include <iostream>
#include <vector>
#include <cstring> //for memory() function
using namespace std;

int n, num, str, ball;
bool ans[1001];
string temp, compare1, compare2;
int s_cnt, b_cnt;

int main(){
    cin >> n;
    int ret = 0;
    memset(ans, true, sizeof(ans));

    for(int i = 123; i <= 987; i++){
        temp = to_string(i);
            
        if(temp[0] == temp[1] || temp[1] == temp[2] || temp[0] == temp[2]) ans[i] = false;
        if(temp[0] - '0'  == 0 || temp[1] - '0'  == 0 || temp[2] - '0' == 0) ans[i] = false;
    }
    for (int i=1;i<=n;i++) {
        cin >> num >> str >> ball;

        for (int i=123;i<=987;i++) {
            s_cnt = 0;
            b_cnt = 0;

            if (ans[i]) {
                compare1 = to_string(num);
                compare2 = to_string(i);

                for (int j=0;j<3;j++) {
                    for (int k=0;k<3;k++) {
                        if (j == k && compare1[j] == compare2[k]) s_cnt++;
                        if (j != k && compare1[j] == compare2[k]) b_cnt++;
                    }
                }
                if (s_cnt != str || b_cnt != ball) {
                    ans[i] = false;
                }
            }
        }
    }
    for (int i=123;i<=987;i++) {
        if (ans[i]) ret++;
    }

    cout << ret << endl;
    return 0;
}

개선할 점

문자열 관련 함수에 익숙하지 못한 것 같다. to_string을 사용할 생각도 못했다. 문자열 문제를 많이 풀어보자.