ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 2503번 숫자야구
    C++ 2021. 12. 11. 01:31

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

     

    2503번: 숫자 야구

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

    www.acmicpc.net

    맞은 것 같은데 자꾸 에러나서 확인해보니 조건 하나 빼먹었었다... 문제를 꼼꼼하게 보자...

    - 각 자리 수 다 다르고 모든 자리에 0이 들어가면 안된다. 
    - 숫자와 위치까지 맞추면 스트라이크, 숫자만 맞추면 볼
    - 각 자리별로 비교해야 하므로 문자열로 만들어서 비교하자

     


    < 코드 작성 전 정리 한 것 >

    - 질문을 통해 답변받은 숫자들은 구조체 형태로 정리하고 구조체 배열에 각각 넣어두었다. num은 문자열 형태로 넣어두었다. (어차피 나중에 한 자리씩 비교해야 하니까)

    num 123 356 327 489
    strike 1 1 2 0
    ball 1 0 0 1

    - 각 숫자별로 비교할 때 중첩 for문 사용해서 탐색해야 한다. 단순 숫자만 같아서 ball인지, 위치까지 같아서 strike인지 개수 세야하기 때문

    - 123~987까지만 탐색하면 된다. (이 때 987 이하이므로 =붙여줘야함) 세자리 숫자들을 모두 돌면서, 사전에 입력된 검사 결과들( ex 123이면 스트라이크 1 볼 1 이런식)과 비교해서 맞는 조건인지 확인.

    - 모든 조건 만족시에만 정답에 넣을 것 (answer vector사용, 나중에 size만 출력해줬음)


    우선 전체 코드... 

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    struct Number {
        string number;
        int strike;
        int ball;
    };
    vector <Number> numbers;
    vector <string> answers;
    
    bool checkNum(string num) {
        if (num[0] == '0' || num[1] == '0' || num[2] == '0') {
            return false;
        }
        else if (num[0] == num[1] || num[1] == num[2] || num[0] == num[2]) {
            return false;
        }
        else {
            return true;
        }
    }
    
    bool compareNum(string num, string comparenum, int strike, int ball) {
        int i, j, strike_count = 0, ball_count = 0;
        for (i=0; i<3; i++) {
            for (j=0; j<3; j++) {
                if (num[i] == comparenum[j]) {
                    if (i == j) {
                        strike_count++; 
                    }
                    else {
                        ball_count++; 
                    }
                }
            }
        }
        
        if (strike_count == strike && ball_count == ball) {
            return true;
        } 
        else {
            return false;
        }
    }
    
    int main() {
        int i, j, size, strike, ball;
        string num, temp;
        bool flag;
        cin>>size;
        for (i=0; i<size; i++) {
            Number number;
            cin>>num;
            cin>>strike;
            cin>>ball;
            number.number = num;
            number.strike = strike;
            number.ball = ball;
            numbers.push_back(number);
        }
    
        for (i=123; i<=987; i++) {
            flag = true;
            temp = to_string(i); 
            if (!checkNum(temp)) {
                continue;
            }
            else {
                for (j=0; j<size; j++) { 
                    if (!compareNum(temp, numbers[j].number, numbers[j].strike, numbers[j].ball)) {
                       flag = false;
                       break;
                    }
                }
            }
            if (flag == true) {
                answers.push_back(temp);
            }
        }
        cout<<answers.size();
    }

     


    각 코드 별 부연설명

    1. checkNum

    bool checkNum(string num) {
        if (num[0] == '0' || num[1] == '0' || num[2] == '0') {
            return false;
        }
        else if (num[0] == num[1] || num[1] == num[2] || num[0] == num[2]) {
            return false;
        }
        else {
            return true;
        }
    }

    123~987 숫자 중에서 0이 들어가거나, 각 자릿수 중 하나라도 겹치는 부분 있는 숫자는 탐색 대상에서 제거해야 한다. 그러기 위해 만든 함수. 

     

     

    2. compareNum

    매개변수로 검사할 숫자인 num과 이미 numbers구조체 벡터에 넣어둔 각 숫자들을 비교해서 strike개수와 ball개수가 맞는지 비교하는 함수이다.  

    bool compareNum(string num, string comparenum, int strike, int ball) {
        int i, j, strike_count = 0, ball_count = 0; 
        for (i=0; i<3; i++) {
            for (j=0; j<3; j++) {
                if (num[i] == comparenum[j]) {
                    if (i == j) {
                        strike_count++; //자리까지 같으면 strike조건에 만족하는 것
                    }
                    else {
                        ball_count++; // 숫자는 같으나 자리가 다르면 ball
                    }
                }
            }
        }
    
        //최종적으로 ball개수랑 strike개수가 원래거랑 맞는지 확인
        if (strike_count == strike && ball_count == ball) {
            return true;
        } 
        else {
            return false;
        }
    }

     

    3. 메인함수 

    int main() {
        int i, j, size, strike, ball;
        string num, temp;
        bool flag;
        
        cin>>size; // 검증된 숫자 개수 
        
        for (i=0; i<size; i++) {
            Number number;
            cin>>num;
            cin>>strike;
            cin>>ball;
    
            number.number = num;
            number.strike = strike;
            number.ball = ball;
    
            numbers.push_back(number); // 검사된 숫자들 넣어둠.
        }
    
        for (i=123; i<=987; i++) {
            flag = true;
            temp = to_string(i); // 각 숫자별 비교를 위해 문자열로 전환
            if (!checkNum(temp)) {
                continue; // 겹치는 숫자 있을경우 연산 필요 없이 다음 숫자로 넘김
            }
            else {
                for (j=0; j<size; j++) { // 검증 횟수만큼 숫자 검사
                    if (!compareNum(temp, numbers[j].number, numbers[j].strike, numbers[j].ball)) {
                       flag = false;
                       break;
                    }
                }
            }
            if (flag == true) {
                answers.push_back(temp);
            }
        }
        
        cout<<answers.size();
    }

    numbers가 질의응답 했던 숫자들 담아둔 구조체 배열이고, 응답의 모든 조건들을 다 검사해야 하고, 그 각각의 스트라이크 / 볼 횟수가 다 일치해야만 answers에 추가한다. 하나라도 false뜨면 안되므로 flag변수를 하나 넣어놨다. 

     

Designed by Tistory.