-
백준 2503번 숫자야구C++ 2021. 12. 11. 01:31
https://www.acmicpc.net/problem/2503
맞은 것 같은데 자꾸 에러나서 확인해보니 조건 하나 빼먹었었다... 문제를 꼼꼼하게 보자...- 각 자리 수 다 다르고 모든 자리에 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변수를 하나 넣어놨다.
'C++' 카테고리의 다른 글
백준 13458번 시험감독 (0) 2021.12.11 카카오 2018 코테 문제2 LZW 압축 문제 (C++) (0) 2021.10.02 연속된 자연수의 합 (백준 2018번 : 수들의 합 5) (0) 2021.09.11