hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie

hyelie

PS/PS Log

22.08.15. 풀었던 문제들 *** vector erase, remove

프로그래머스 코딩테스트 실전 대비 모의고사 3회

1번

 주어진 대로 반복문을 써서 풀면 되는 문제.

int solution(int give, int take, int cur) {
    int answer = 0;

    while(cur >= give){ // 현재 가지고 있는 게 주는 것보다 많으면 줄 수 이씅ㅁ
        int ret = (cur / give) * take; // 돌려받는 것
        answer += ret;
        cur = cur - ((cur / give) * give) + ret; // 현재 개수 = 현재 개수 - 준 것 + 돌려받은 것
    }

    return answer;
}

 

2번

 뒤에서 4개가 주어진 조건을 만족한다면, 그것을 빼고 추가하면 되는 문제. list를 쓸까 vector를 쓸까 고민하다가 결국 더 빠른 vector를 선택했다. vector의 erase, remove의 차이에 대해 알아두자.

int solution(vector<int> ingredients) {
    int answer = 0;

    vector<int> cur;
    for(int i = 0, cidx = 0; i<ingredients.size(); i++){
        cur.push_back(ingredients[i]);
        int csize = cur.size();
        if(csize >= 4){
            if(cur[csize-1] == 1 && cur[csize-2] == 3 && cur[csize-3] == 2 && cur[csize-4] == 1){
                cur.erase(cur.begin() + csize - 4, cur.end());
                answer++;
            }
        }
    }

    return answer;
}

 

3번

 '경계 지역'에 근무를 서는 최솟값을 알아내면 되는 문제. 문제 자체는 [1 <= (i % cycle_time) <= guard[2]]라는 규칙이 있어서 쉬운데, 모든 경계 지역에 대해 이 값을 알아내야 하면 시간초과가 날 것 같았는데, 생각보다 테스트 케이스가 빈약했던 문제. 

bool cmp(vector<int>& a, vector<int>& b){
    if(a[0] == b[0]){
        if(a[1] == b[1]){
            if(a[2] == b[2]){
                return a[3] < b[3];
            }
            return a[2] < b[2];
        }
        return a[1] < b[1];
    }
    return a[0] < b[0];
}

int solution(int distance, vector<vector<int>> scope, vector<vector<int>> times) {
    vector<vector<int>> guards(scope.size());
    // [i][0] : 경계 시작 지점, [i][1] : 경계 끝 지점
    // [i][2] : 근무 시간, [i][3] : 휴식 시간
    for(int i = 0; i<scope.size(); i++){
        if(scope[i][0] > scope[i][1]){
            guards[i].push_back(scope[i][1]);
            guards[i].push_back(scope[i][0]);
        }
        else{
            guards[i].push_back(scope[i][0]);
            guards[i].push_back(scope[i][1]);
        }
        guards[i].push_back(times[i][0]);
        guards[i].push_back(times[i][1]);
    }
    sort(guards.begin(), guards.end(), cmp);

    int answer = distance;
    for(vector<int>& guard : guards){
        int cycle_time = guard[2] + guard[3];
        // 감시하는 구간에 근무시간이라면 break
        // 어떤 i가 근무 시간에 있는 건...
        // 1 <= (i % cycle_time) <= guard[2]
        // 이면 근무 시간이라는 것을 판별할 수 있음
        for(int i = guard[0]; i<=guard[1]; i++){
            int remainder = i%cycle_time;
            if(1 <= remainder &&  remainder <= guard[2]){
                answer = min(answer, i);
            }
        }
    }
    
    return answer;
}

 

4번

 꽤나 재밌었던 문제. DFS의 특성을 이용해서 [현재 칸을 색칠하는 경우, 그렇지 않은 경우]에 대해 최소 색칠 횟수를 leaf에서부터 가지고 올라와야 한다.

 만약 parent를 색칠했다면 child는 색칠해도 되고, 색칠하지 않아도 되므로 parent.first(색칠한 경우) += min(child를 색칠한 경우, child를 색칠하지 않은 경우)이고, parent를 색칠하지 않았다면 child는 색칠해야 하므로 parent.second(색칠하지 않은 경우) += child를 색칠한 경우로 문제를 풀면 된다.

typedef pair<int, int> pii;
int N;
vector<int> visited;
vector<vector<int>> edges;

// .first : cur을 색 칠한 경우 최소 색칠 횟수, .second : cur을 색칠하지 않은 경우 최소 색칠 횟수
pii dfs(int cur){
    visited[cur] = true;

    pii result = {1, 0}; // .first : cur을 색칠한 경우 
    for(int adj : edges[cur]){
        if(!visited[adj]){
            pii child_result = dfs(adj);
            result.first += min(child_result.first, child_result.second);
            // cur을 색칠했다면 child는 색칠해도 되고, 안 해도 됨
            result.second += child_result.first;
            // cur을 색칠하지 않았다면 child을 색칠되어 있어야 함
        }
    }
    return result; // child가 없다면 {1, 0}을 리턴.
}

int solution(int n, vector<vector<int>> lighthouse) {
    N = n+1;
    visited.resize(N);
    fill(visited.begin(), visited.end(), false);
    edges.resize(N);
    for(vector<int>& vi : lighthouse){
        edges[vi[0]].push_back(vi[1]);
        edges[vi[1]].push_back(vi[0]);
    }

    pii answer = dfs(1);

    return min(answer.first, answer.second);
}

'PS > PS Log' 카테고리의 다른 글

22.08.17. 풀었던 문제들  (0) 2022.08.20
22.08.16. 풀었던 문제들  (0) 2022.08.16
22.08.14. 풀었던 문제들  (0) 2022.08.15
22.08.13. 풀었던 문제들  (0) 2022.08.13
22.08.12. 풀었던 문제들 - Codeforces #805 Div. 3 4/7  (0) 2022.08.13
    hyelie
    hyelie

    티스토리툴바