https://school.programmers.co.kr/learn/courses/30/lessons/138475
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
과정
- starts가 정렬이 되어 있지 않으므로 starts의 값과 해당 index를 vector에 담아준 뒤 starts의 값이 작은 순으로 정렬해준다.
- e이하의 숫자들에 대한 등장 횟수를 구한다.
- 등장 횟수의 내림차 순 숫자에 대한 오름차 순으로 정렬을 한다.
- start_arr(starts의 값과 인덱스가 담겨 정렬이 된 배열)에서 앞부터 값을 꺼내 만약 starts의 값보다 작다면 answer에 해당 인덱스에 cnt 초기 숫자 값을 저장해준다.
start_arr = <start값, 초기 인덱스> (정렬을 이용하여 연산을 줄이기 위함)
cnt = <초기 숫자, 등장 횟수> (정렬을 이용하여 반복적인 탐색을 피하기 위함)
생각해보기
값들의 count 횟수를 구할 때 메모이제이션과 소수만을 이용하여 계산하면 훨씬 빠르지 않을까...?
코드
더보기
#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
#include <stack>
using namespace std;
//정렬 후 스택에 넣었던 걸 뺀다? -> 숫자순 이므로 가능 할 수도 sqrt
vector<pair<int, int> > cnt;
vector<pair<int, int> > start_arr;
bool cmp(const pair<int, int>& a, const pair<int, int>& b ){
if(a.second == b.second){
return a.first < b.first;
}
return a.second > b.second;
}
void calc(int e){
for(int i=0;i<=e;++i){
cnt[i].first=i;
cnt[i].second=0;
}
for(int i=1;i<=sqrt(e);++i){
for(int j=i;j*i<=e;++j){
cnt[i*j].first=i*j;
if(i==j)
cnt[i*j].second+=1;
else
cnt[i*j].second+=2;
}
}
}
vector<int> solution(int e, vector<int> starts) {
vector<int> answer(starts.size());
cnt.resize(e+1);//곱한 값이 최대 e까지 밖에 안나오므로
int len=starts.size();
for(int i=0;i<len;++i){
start_arr.push_back({starts[i],i});
}
sort(start_arr.begin(),start_arr.end());
calc(e);
sort(cnt.begin(),cnt.end(),cmp);
int idx=0;
for(int i=0;i<len;++i){
while(cnt[idx].first < start_arr[i].first)
++idx;
answer[start_arr[i].second] = cnt[idx].first;
}
return answer;
}
728x90
'알고리즘 > 프로그래머스 문제' 카테고리의 다른 글
| [ALGORITHM] LEVEL3 2022 KAKAO TECH INTERNSHIP - 등산코스 정하기 (0) | 2022.12.14 |
|---|---|
| [ALGORITHM] LEVEL4 - 쌍둥이 빌딩 숲 (0) | 2022.12.03 |
| [ALGORITHM] LEVEL2 - 귤 고르기 (0) | 2022.11.28 |
| [ALGORITHM] LEVEL2 - 택배상자 (0) | 2022.10.27 |
| [ALGORITHM] LEVEL2 - 롤케이크 자르기 (0) | 2022.10.26 |
댓글