🔥 난이도
Level2
📝 문제설명
[본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.]
카카오는 하반기 경력 개발자 공개채용을 진행 중에 있으며 현재 지원서 접수와 코딩테스트가 종료되었습니다. 이번 채용에서 지원자는 지원서 작성 시 아래와 같이 4가지 항목을 반드시 선택하도록 하였습니다.
- 코딩테스트 참여 개발언어 항목에 cpp, java, python 중 하나를 선택해야 합니다.
- 지원 직군 항목에 backend와 frontend 중 하나를 선택해야 합니다.
- 지원 경력구분 항목에 junior와 senior 중 하나를 선택해야 합니다.
- 선호하는 소울푸드로 chicken과 pizza 중 하나를 선택해야 합니다.
인재영입팀에 근무하고 있는 니니즈
는 코딩테스트 결과를 분석하여 채용에 참여한 개발팀들에 제공하기 위해 지원자들의 지원 조건을 선택하면 해당 조건에 맞는 지원자가 몇 명인 지 쉽게 알 수 있는 도구를 만들고 있습니다.
예를 들어, 개발팀에서 궁금해하는 문의사항은 다음과 같은 형태가 될 수 있습니다.
코딩테스트에 java로 참여했으며, backend 직군을 선택했고, junior 경력이면서, 소울푸드로 pizza를 선택한 사람 중 코딩테스트 점수를 50점 이상 받은 지원자는 몇 명인가?
물론 이 외에도 각 개발팀의 상황에 따라 아래와 같이 다양한 형태의 문의가 있을 수 있습니다.
- 코딩테스트에 python으로 참여했으며, frontend 직군을 선택했고, senior 경력이면서, 소울푸드로 chicken을 선택한 사람 중 코딩테스트 점수를 100점 이상 받은 사람은 모두 몇 명인가?
- 코딩테스트에 cpp로 참여했으며, senior 경력이면서, 소울푸드로 pizza를 선택한 사람 중 코딩테스트 점수를 100점 이상 받은 사람은 모두 몇 명인가?
- backend 직군을 선택했고, senior 경력이면서 코딩테스트 점수를 200점 이상 받은 사람은 모두 몇 명인가?
- 소울푸드로 chicken을 선택한 사람 중 코딩테스트 점수를 250점 이상 받은 사람은 모두 몇 명인가?
- 코딩테스트 점수를 150점 이상 받은 사람은 모두 몇 명인가?
즉, 개발팀에서 궁금해하는 내용은 다음과 같은 형태를 갖습니다.
* [조건]을 만족하는 사람 중 코딩테스트 점수를 X점 이상 받은 사람은 모두 몇 명인가?
[문제]
지원자가 지원서에 입력한 4가지의 정보와 획득한 코딩테스트 점수를 하나의 문자열로 구성한 값의 배열 info, 개발팀이 궁금해하는 문의조건이 문자열 형태로 담긴 배열 query가 매개변수로 주어질 때,
각 문의조건에 해당하는 사람들의 숫자를 순서대로 배열에 담아 return 하도록 solution 함수를 완성해 주세요.
⌛️ 제한 조건
- info 배열의 크기는 1 이상 50,000 이하입니다.
- info 배열 각 원소의 값은 지원자가 지원서에 입력한 4가지 값과 코딩테스트 점수를 합친 "개발언어 직군 경력 소울푸드 점수" 형식입니다.
- 개발언어는 cpp, java, python 중 하나입니다.
- 직군은 backend, frontend 중 하나입니다.
- 경력은 junior, senior 중 하나입니다.
- 소울푸드는 chicken, pizza 중 하나입니다.
- 점수는 코딩테스트 점수를 의미하며, 1 이상 100,000 이하인 자연수입니다.
- 각 단어는 공백문자(스페이스 바) 하나로 구분되어 있습니다.
- query 배열의 크기는 1 이상 100,000 이하입니다.
- query의 각 문자열은 "[조건] X" 형식입니다.
- [조건]은 "개발언어 and 직군 and 경력 and 소울푸드" 형식의 문자열입니다.
- 언어는 cpp, java, python, - 중 하나입니다.
- 직군은 backend, frontend, - 중 하나입니다.
- 경력은 junior, senior, - 중 하나입니다.
- 소울푸드는 chicken, pizza, - 중 하나입니다.
- '-' 표시는 해당 조건을 고려하지 않겠다는 의미입니다.
- X는 코딩테스트 점수를 의미하며 조건을 만족하는 사람 중 X점 이상 받은 사람은 모두 몇 명인 지를 의미합니다.
- 각 단어는 공백문자(스페이스 바) 하나로 구분되어 있습니다.
- 예를 들면, "cpp and - and senior and pizza 500"은 "cpp로 코딩테스트를 봤으며, 경력은 senior 이면서 소울푸드로 pizza를 선택한 지원자 중 코딩테스트 점수를 500점 이상 받은 사람은 모두 몇 명인가?"를 의미합니다.
🖨 입출력 예
info | query | result |
---|---|---|
["java backend junior pizza 150", "python frontend senior chicken 210", "python frontend senior chicken 150", "cpp backend senior pizza 260", "java backend junior chicken 80", "python backend senior chicken 50"] |
["java and backend and junior and pizza 100", "python and frontend and senior and chicken 200", "cpp and - and senior and pizza 250", "- and backend and senior and - 150", "- and - and - and chicken 100", "- and - and - and - 150"] |
[1,1,1,1,2,4] |
✍🏻 풀이 및 분류
이진 탐색
,트라이
처음 이 문제를 풀었을 때는 제한사항을 제대로 보지 않고 2중 for 문을 사용하여 문제를 풀었다. 하지만 결과는 정확성 테스트만 통과하고 최대 시간 복잡도가 50,000 * 100,000
이기 때문에 효율성 테스트는 통과하지 못했다.
시간 복잡도를 보고 이 문제는 이진 탐색을 활용해야 효율성 테스트를 통과하겠다고 생각했다.
먼저 info
문자열들을 분리한다.
개발언어
- cpp : 0
- java : 1
- python : 2
직군
- backend : 0
- frontend : 1
경력
- junior : 0
- sinior : 1
소울푸드
- chicken : 0
- pizza : 1
나누어진 정보들을 위와 같이 분류하여 4차원 벡터에 점수를 입력한다. 그리고 이진 탐색을 쓰기 위해 정렬해 준다.
예시) java backend junior pizza가 주어지면 table[1][0][0][1]에 점수를 삽입함
query
도 info
와 마찬가지로 문자열들을 모두 분리하여 4중 for 문을 이용해 해당하는 지원자를 찾는다.
-일 경우는 -1을 넣어주고 -1이거나 해당하는 번호라면 다음 for 문으로 이동함
그리고 lower_bound()
함수를 이용해 기준 점수 이상인 지원자를 찾고 해당하는 지원자 수를 answer
에 넣어준다.
💻 풀이 코드
효율성 테스트 실패
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
vector<string> split(string s) {
vector<string> ret;
istringstream ss(s);
string buffer;
while(getline(ss, buffer, ' ')) {
if (buffer == "and") continue;
ret.push_back(buffer);
}
return ret;
}
int exploreTable(vector<vector<string> > table, vector<string> query) {
int ret = 0;
for (int i = 0; i < table.size(); i++) {
bool flag = true;
for (int j = 0; j < query.size(); j++) {
if (query[j] == "-") continue;
if (j == query.size() - 1) {
if (stoi(table[i][j]) < stoi(query[j])) {
flag = false;
}
break;
}
if (table[i][j] != query[j]) {
flag = false;
break;
}
}
if (flag) ret += 1;
}
return ret;
}
vector<int> solution(vector<string> info, vector<string> query) {
vector<int> answer;
vector<vector<string> > table;
table.reserve(info.size());
for (int i = 0; i < info.size(); i++) {
vector<string> inp = split(info[i]);
table.push_back(inp);
}
for (string s : query) {
vector<string> temp = split(s);
answer.push_back(exploreTable(table, temp));
}
return answer;
}
정답
#include <bits/stdc++.h>
using namespace std;
vector<int> table[3][2][2][2];
vector<string> split(string s) {
vector<string> ret;
istringstream ss(s);
string buffer;
while(getline(ss, buffer, ' ')) {
if (buffer == "and") continue;
ret.push_back(buffer);
}
return ret;
}
void enterInfoData(string s) {
vector<string> temp = split(s);
int language = 0, job = 0, career = 0, food = 0, score = 0;
for (string type : temp) {
if (!type.compare("cpp")) language = 0;
else if (!type.compare("java")) language = 1;
else if (!type.compare("python")) language = 2;
else if (!type.compare("backend")) job = 0;
else if (!type.compare("frontend")) job = 1;
else if (!type.compare("junior")) career = 0;
else if (!type.compare("senior")) career = 1;
else if (!type.compare("chicken")) food = 0;
else if (!type.compare("pizza")) food = 1;
else score = stoi(type);
}
table[language][job][career][food].push_back(score);
}
void sortTable() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
for (int l = 0; l < 2; l++) {
sort(table[i][j][k][l].begin(), table[i][j][k][l].end());
}
}
}
}
}
int excuteQuery(vector<string> v) {
int language = 0, job = 0, career = 0, food = 0, score = 0, cnt = 0;
for (int i = 0; i < v.size(); i++) {
string type = v[i];
if (!type.compare("-")) {
if (i == 0) language = -1;
else if (i == 1) job = -1;
else if (i == 2) career = -1;
else if (i == 3) food = -1;
else score = -1;
}
else if (!type.compare("cpp")) language = 0;
else if (!type.compare("java")) language = 1;
else if (!type.compare("python")) language = 2;
else if (!type.compare("backend")) job = 0;
else if (!type.compare("frontend")) job = 1;
else if (!type.compare("junior")) career = 0;
else if (!type.compare("senior")) career = 1;
else if (!type.compare("chicken")) food = 0;
else if (!type.compare("pizza")) food = 1;
else score = stoi(type);
}
for (int i = 0; i < 3; i++) {
if (language != -1 && language != i) continue;
for (int j = 0; j < 2; j++) {
if (job != -1 && job != j) continue;
for (int k = 0; k < 2; k++) {
if (career != -1 && career != k) continue;
for (int l = 0; l < 2; l++) {
if (food != -1 && food != l) continue;
auto it = lower_bound(table[i][j][k][l].begin(), table[i][j][k][l].end(), score);
for (; it != table[i][j][k][l].end(); it++)
cnt += 1;
}
}
}
}
return cnt;
}
vector<int> solution(vector<string> info, vector<string> query) {
vector<int> answer;
for (string s : info) {
enterInfoData(s);
}
sortTable();
for (string s : query) {
vector<string> v = split(s);
answer.push_back(excuteQuery(v));
}
return answer;
}
'Algorithm > 프로그래머스' 카테고리의 다른 글
[cpp] 프로그래머스 - 거리두기 확인하기 (2021 카카오 채용 연계형 인턴십) (0) | 2022.02.15 |
---|---|
[cpp] 프로그래머스 - 신규 아이디 추천 (2021 KAKAO BLIND RECRUITMENT) (0) | 2022.02.15 |
[cpp] 프로그래머스 - 메뉴 리뉴얼 (2021 KAKAO BLIND RECRUITMENT) (0) | 2022.02.15 |
[자바] 프로그래머스 - [1차] 프렌즈4블록 (2018 KAKAO BLIND RECRUITMENT) (0) | 2022.02.15 |
[자바] 프로그래머스 - 피로도 (Level2) (0) | 2022.02.15 |