문제
https://programmers.co.kr/learn/courses/30/lessons/72412
걸린 시간
01 : 14 : 48 실패
풀이
C++
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <algorithm>
using namespace std;
bool compare(int a, int b){
return a < b;
}
vector<string> split(string input, char delimiter){
vector<string> ret;
istringstream iss(input);
string token;
while(getline(iss, token, delimiter))
ret.push_back(token);
return ret;
}
vector<int> solution(vector<string> info, vector<string> query) {
map<string, int> m;
m["cpp"] = 0;
m["java"] = 1;
m["python"] = 2;
m["backend"] = 0;
m["frontend"] = 1;
m["junior"] = 0;
m["senior"] = 1;
m["chicken"] = 0;
m["pizza"] = 1;
vector<int> answer;
vector<int> db[3][2][2][2];
for(string i : info){
vector<string> s = split(i, ' ');
db
[m[s[0]]]
[m[s[1]]]
[m[s[2]]]
[m[s[3]]].push_back(stoi(s[4]));
}
for(int l = 0; l < 3; l++){
for(int j = 0; j < 2; j++){
for(int c = 0; c < 2; c++){
for(int f = 0; f < 2; f++){
sort(db[l][j][c][f].begin(), db[l][j][c][f].end(), compare);
}
}
}
}
for(string i : query){
vector<string> s = split(i, ' ');
int ls, le, js, je, cs, ce, fs, fe;
if(s[0] == "-") ls = 0, le = 2;
else ls = le = m[s[0]];
if(s[2] == "-") js = 0, je = 1;
else js = je = m[s[2]];
if(s[4] == "-") cs = 0, ce = 1;
else cs = ce = m[s[4]];
if(s[6] == "-") fs = 0, fe = 1;
else fs = fe = m[s[6]];
int cnt = 0;
for(int l = ls; l <= le; l++){
for(int j = js; j <= je; j++){
for(int c = cs; c <= ce; c++){
for(int f = fs; f <= fe; f++){
vector<int> &point = db[l][j][c][f];
auto iter = lower_bound(point.begin(), point.end(), stoi(s[7]));
if(iter == point.end()) continue;
cnt += point.size()-(iter-point.begin());
}
}
}
}
answer.push_back(cnt);
}
return answer;
}
지원자가 입력한 4가지 항목의 문자열을 인덱스화 할 생각을 하지 못해 -
입력 시 어떤 식으로 6,561(3^2^2^2) 가지의 분류를 확인해야할 지 몰랐다.
점수 배열을 미리 오름차순 정렬해두고 이분 탐색을 이용한다면, X 점 이상의 지원자의 수를 구하는 연산을 상수 시간으로 줄일 수 있었다.
새롭게 알게 된 지식이 두 가지가 있다.
- 이진 탐색을 하되, 주어진 값들 중에서 기준이 되는 값 보다 크거나 같은 값들 중 제일 작은 값의 반복자를 반환하는 lower_bound 함수
- 반복자간 사칙 연산을 수행하면 정수형의 결과값을 가짐
JavaScript
function solution(info, query) {
const answer = [];
const lower_bound = (li, k) => {
let m = 0;
let l = 0;
let r = li.length-1;
while(l <= r){
m = Math.floor((l+r)/2);
if(k <= li[m]) r = m-1;
else l = m+1;
}
return k > li[m] ? m+1 : m;
}
const n_array = (li, i, n, el) => {
if(i === li.length-1){
if(typeof el === 'object'){
const tmp = Array(li[i]);
for(let i = 0; i < li[i]; i++)
tmp[i] = JSON.parse(JSON.stringify(el))
return tmp;
}
else return Array(li[i]).fill(el);
}
else return Array.from(Array(li[i]), () => n_array(li, i+1, n, el))
}
const db = n_array([3, 2, 2, 2], 0, 4, []);
const d = {};
d.cpp = d.backend = d.junior = d.chicken = 0;
d.java = d.frontend = d.senior = d.pizza = 1;
d.python = 2;
for(let i of info){
let t = i.split(' ');
db
[d[t[0]]]
[d[t[1]]]
[d[t[2]]]
[d[t[3]]].push(parseInt(t[4]));
}
for(let i = 0; i < 3; i++){
for(let j = 0; j < 2; j++){
for(let k = 0; k < 2; k++){
for(let l = 0; l < 2; l++){
li = db[i][j][k][l];
li.sort((a, b) => {
if(a > b) return 1;
else return -1;
});
}
}
}
}
for(let q of query){
let t = q.split(/and|\s/).filter(el => el !== '');
let cnt = 0;
// < > 가 || 보다 우선순위가 높다.
for(let i = (d[t[0]] || 0); i < (d[t[0]]+1 || 3); i++){
for(let j = (d[t[1]] || 0); j < (d[t[1]]+1 || 2); j++){
for(let k = (d[t[2]] || 0); k < (d[t[2]]+1 || 2); k++){
for(let l = (d[t[3]] || 0); l < (d[t[3]]+1 || 2); l++){
let li = db[i][j][k][l];
cnt += li.length - lower_bound(li, parseInt(t[4]));
}
}
}
}
answer.push(cnt)
}
return answer;
}
- 4가지 항목의 요소들을 인덱스화해서 지원자 점수를 배열에 저장한다.
- 효율성 테스트를 통과하기 위해 배열을 정렬한 후 이진탐색을 이용해
X
점 이상의 지원자 수를 센다.
중복된 값이 존재하는 지원자의 점수 오름차순 배열에서 X
점 보다 크거나 같은 인덱스를 찾아야 하므로, 하한선 lower bound 이진 탐색 알고리즘을 구현해 사용하면 된다.
기억해야 할 것
- 정렬 함수
javascript array 객체 sort 메소드의 비교함수
c++ algorithm 라이브러리 sort 함수의 비교함수
c++ 은 bool 값에 따라 앞의 요소 a
가 뒤의 요소 b
보다 먼저 이동한다고 표현되어 있는데, a
가 b
의 앞으로 온다는 이야기인 것 같다.
즉, c++ 의 true 가 javascript 의 -1 과 같고, false 가 1 과 같다.
- 연산자 우선순위
문제에서 -
의 처리를 위해 or 을 의미하는 ||
를 for 문 안에 사용했지만, or 기호는 조건식의 비교문자 <, >
보다 연산자 우선순위가 낮아 의도한대로 값이 대입되지 않았다. 괄호를 사용해서 우선순위를 바꾸어주어야 한다.
'programmers' 카테고리의 다른 글
programmers Level 2 주차 요금 계산 (0) | 2022.04.24 |
---|---|
programmers Level 2 k진수에서 소수 개수 구하기 (0) | 2022.04.24 |
programmers Level 3 모두 0으로 만들기 (0) | 2021.04.16 |
programmers Level 4 무지의 먹방 라이브 (1) | 2020.12.06 |
2021 KAKAO BLIND RECRUITMENT 1차 코딩테스트 (1, 2번) (0) | 2020.09.12 |
댓글