문제 설명
로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다.
아래는 로또의 순위를 정하는 방식입니다.
순위 | 당첨 내용 |
1 | 6개 번호가 모두 일치 |
2 | 5개 번호가 일치 |
3 | 4개 번호가 일치 |
4 | 3개 번호가 일치 |
5 | 2개 번호가 일치 |
6(낙첨) | 그 외 |
로또를 구매한 민우는 당첨 번호 발표일을 학수고대하고 있었습니다.
하지만, 민우의 동생이 로또에 낙서를 하여, 일부 번호를 알아볼 수 없게 되었습니다.
당첨 번호 발표 후, 민우는 자신이 구매했던 로또로 당첨이 가능했던 최고 순위와 최저 순위를 알아보고 싶어 졌습니다.
알아볼 수 없는 번호를 0으로 표기하기로 하고, 민우가 구매한 로또 번호 6개가 44, 1, 0, 0, 31 25라고 가정해보겠습니다. 당첨 번호 6개가 31, 10, 45, 1, 6, 19라면, 당첨 가능한 최고 순위와 최저 순위의 한 예는 아래와 같습니다.
당첨 번호 | 31 | 10 | 45 | 1 | 6 | 19 | 결과 |
최고 순위 번호 | 31 | 0→10 | 44 | 1 | 0→6 | 25 | 4개 번호 일치, 3등 |
최저 순위 번호 | 31 | 0→11 | 44 | 1 | 0→7 | 25 | 2개 번호 일치, 5등 |
- 순서와 상관없이, 구매한 로또에 당첨 번호와 일치하는 번호가 있으면 맞힌 걸로 인정됩니다.
- 알아볼 수 없는 두 개의 번호를 각각 10, 6이라고 가정하면 3등에 당첨될 수 있습니다.
- 3등을 만드는 다른 방법들도 존재합니다. 하지만, 2등 이상으로 만드는 것은 불가능합니다.
- 알아볼 수 없는 두 개의 번호를 각각 11, 7이라고 가정하면 5등에 당첨될 수 있습니다.
- 5등을 만드는 다른 방법들도 존재합니다. 하지만, 6등(낙첨)으로 만드는 것은 불가능합니다.
민우가 구매한 로또 번호를 담은 배열 lottos, 당첨 번호를 담은 배열 win_nums가 매개변수로 주어집니다. 이때, 당첨 가능한 최고 순위와 최저 순위를 차례대로 배열에 담아서 return 하도록 solution 함수를 완성해주세요.
제한사항
- lottos는 길이 6인 정수 배열입니다.
- lottos의 모든 원소는 0 이상 45 이하인 정수입니다.
- 0은 알아볼 수 없는 숫자를 의미합니다.
- 0을 제외한 다른 숫자들은 lottos에 2개 이상 담겨있지 않습니다.
- lottos의 원소들은 정렬되어 있지 않을 수도 있습니다.
- win_nums은 길이 6인 정수 배열입니다.
- win_nums의 모든 원소는 1 이상 45 이하인 정수입니다.
- win_nums에는 같은 숫자가 2개 이상 담겨있지 않습니다.
- win_nums의 원소들은 정렬되어 있지 않을 수도 있습니다.
입출력 예
lottos | win_nums | result |
[44, 1, 0, 0, 31, 25] | [31, 10, 45, 1, 6, 19] | [3, 5] |
[0, 0, 0, 0, 0, 0] | [38, 19, 20, 40, 15, 25] | [1, 6] |
[45, 4, 35, 20, 3, 9] | [20, 9, 3, 45, 4, 35] | [1, 1] |
입출력 예 설명
입출력 예 #1
문제 예시와 같습니다.
입출력 예 #2
알아볼 수 없는 번호들이 아래와 같았다면, 1등과 6등에 당첨될 수 있습니다.
당첨 번호 | 38 | 16 | 20 | 40 | 15 | 25 | 결과 |
최고 순위 번호 | 0→38 | 0→19 | 0→20 | 0→40 | 0→15 | 0→25 | 6개 번호 일치, 1등 |
최저 순위 번호 | 0→21 | 0→22 | 0→23 | 0→24 | 0→26 | 0→27 | 0개 번호 일치, 6등 |
입출력 예 #3
민우가 구매한 로또의 번호와 당첨 번호가 모두 일치하므로, 최고 순위와 최저 순위는 모두 1등입니다.
- 실제로 사용되는 로또 순위의 결정 방식과는 약간 다르지만,
이 문제에서는 지문에 명시된 대로 로또 순위를 결정하도록 합니다.
#include <string>
#include <vector>
using namespace std;
vector<int> solution(vector<int> lottos, vector<int> win_nums) {
vector<int> answer;
int lottos_len = lottos.size();
int win_nums_len = win_nums.size();
int zero_cnt = 0;
int correct_cnt = 0;
for(int i=0; i<lottos_len; i++) {
if(lottos[i] == 0) {
zero_cnt++;
}
for(int j=0; j<win_nums_len; j++) {
if(lottos[i] == win_nums[j]) {
correct_cnt++;
}
}
}
int high, low;
high = win_nums_len - zero_cnt - correct_cnt + 1;
low = high + zero_cnt;
// low = win_nums_len - correct_cnt + 1;
if(correct_cnt == 0) {
low--;
if(zero_cnt == 0) {
high--;
}
}
answer.push_back(high);
answer.push_back(low);
return answer;
}
일단 등수를 정하는 알고리즘부터 생각해보자.
로또 번호의 총 갯수도 6개이고, 등수도 6등까지 있다.
그러면 6개를 다 맞았을 경우 1등이므로 6 - 맞은 갯수 + 1을 해주면 등수가 나온다.
하지만 0이라는 숫자, 즉 알 수 없는 숫자가 있기 때문에 분기를 나누어 주어야 한다.
최고등수는 0이라는 숫자로 가려진 숫자들이 다 맞았을 경우.
최저등수는 0이라는 숫자로 가려진 숫자들이 다 틀렸을 경우이다.
따라서 최고등수는 6 - 0의 갯수 - 맞은 갯수 + 1 을 해주면된다.
알기 쉽게 바꿔보자면 6 - (0의 갯수 + 맞은 갯수) + 1이다.
0으로 지워진 숫자가 모두 맞는 숫자이므로 0으로 지워지지 않은수중에 맞는수에다가 더해주면 결국,
맞은 숫자의 총 합계가 나온다.
최저등수는 6 - 맞은 갯수 + 1 만 해주면된다.
어차피 0으로 가려진 숫자가 다 틀린것이므로 결과에 상관이 없다.
식을 좀 간단히 하자면 최고등수 + 0의 갯수로 나타내주면된다.
0으로 가려진 숫자가 다맞았기 때문에 빼서 최고등수를 구한것인데, 최저등수는 다틀렸으므로 0의갯수를 뺄 필요가
없기 때문에 그냥 다 더해주는 것이다.
위와 같이 하면되지만, 한가지 경우를 더 생각해주어야 한다.
처음에 이생각을 못해주어서 오류가 나고 결과값을 보니 이해가 되었다.
바로 맞은갯수가 0일경우와 0의 갯수가 0일경우이다.
맞은갯수가 0일경우는 예를들어 0으로 가려진 숫자가 없을경우의 최저등수를 생각해보면된다.
결국 6등인데, 위의 수식에서는 6 - 맞은갯수 + 1 이므로,
맞은갯수와 0을 대입하면 7이라는 결과가 나온다.
등수는 6등까지 밖에 없으므로 맞은갯수가 0일경우는 -1을 해주면된다.
최고등수는 맞은 갯수가 0이라도 0의갯수에 따라 영향을받으므로 신경안써줘도 된다.
하지만 맞은갯수가 0이면서 0의갯수도 0일때는 문제가생긴다.
최고등수는 6 - 0의 갯수 - 맞은 갯수 + 1인데,
맞은 갯수가 0이라도 최고등수는 0의 갯수에 따라 순위에 영향이 있으므로 상관이없었는데,
영향을 주는 변수중 맞은 갯수빼고 0의 갯수마저 0이 되버리면 결국 최고등수도 7등이 되버린다.
따라서 이럴 경우엔 최고등수에 -1을 해주면된다.
'PS > Programmers' 카테고리의 다른 글
Programmers / Level1 / 크레인 인형뽑기 / C++ / JS (0) | 2021.10.14 |
---|---|
Programmers / Level1 / 신규 아이디 추천 / C++ / JS (0) | 2021.10.09 |
Programmers / Level1 / 숫자 문자열과 영단어 / C++ / JS (0) | 2021.10.05 |
Programmers / Level1 / 완주하지 못한 선수 / C++ (0) | 2021.09.28 |