본문 바로가기
코드카타/코딩테스트

기능개발

by WaDDak 2024. 8. 15.

https://school.programmers.co.kr/learn/courses/30/lessons/42586

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이 :

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> progresses, vector<int> speeds) 
{
    vector<int> answer;

    // 작업완료 일수, 
    vector<int> Days;

    for (size_t i = 0; i < progresses.size(); i++)
    {
        int Time = 100 - progresses[i];

        // (a + b - 1) / b 를 통해 정수 연산만으로 나누고 소숫점 올림을 계산할수 있다.
        Time = (Time + speeds[i] - 1) / speeds[i];
        Days.push_back(Time);
    }

    int Count = 1;
    int Completeday = Days[0];

    for (size_t i = 1; i < Days.size(); i++)
    {
        if (Completeday >= Days[i])
        {
            Count++;
        }
        else
        {
            Completeday = Days[i];
            answer.push_back(Count);
            Count = 1;
        }
    }
   answer.push_back(Count);

    return answer;
}

 

설명 : 

  1. 각 작업의 완료 날짜 계산 
    • 각 작업이 100% 완료되기까지 걸리는 날짜를 계산합니다.
    • 예를 들어, 진도가 93%이고 속도가 7%라면, 남은 7%를 채우기 위해 (100 - 93) / 7 = 1 일이 필요하고 이경우 1일이 걸립니다.
  2. 배포 처리 :
    • 작업들은 앞에서부터 차례대로 배포됩니다.
    • 앞의 작업이 완료될 때 같이 배포될 수 있는 뒤의 작업들을 계산합니다.
    • 앞의 작업이 완료되는 날짜보다 뒤의 작업이 완료되는 날짜가 늦다면, 그 뒤의 작업은 새로운 배포 그룹으로 처리됩니다.
  3.  // (a + b - 1) / b 를 통해 정수 연산만으로 나누고 소숫점 올림을 계산할수 있다.
            Time = (Time + speeds[i] - 1) / speeds[i];
    1. (a + b - 1) / b 연산을 통해 정수형 계산 만으로 소숫점 올림 처리를 할 수 있습니다.
      • 예외 사항이 존재합니다. 1. b가 0인경우:
        • 문제 : b가 0이면, 나눗셈 자체가 정의되지 않으며, 프로그램이 런타임 에러를 일으킵니다(분모가 0인 경우 나눗셈은 수학적으로 정의되지 않음)
        • 해결 방법 : 나눗셈을 수행하기 전에 b가 0인지 확인하고, 예외 처리를 통해 이 경우를 처리해야함.
      • 2. a와 b가 음수인 경우:
        • 문제 : 정수 나눗셈과 올림 연산이 음수에 대해서는 양수일 때와 다르게 동작할 수 있습니다.예를들어, a나 b가 음수인 경우 (a + b - 1) / b 의 계산이 예상과 다르게 될 수 있습니다.
        • 해결 방법 : 이 방법은 양수 입력에 대해서만 사용할 것을 권장합니다. 음수 입력이 필요한 경우에는 추가적인 처리나 다른 방법을 고려해야 합니다.
      • 3. a또는 b가 매우 큰 경우:
        • 문제 : a + b -1 계산에서 정수 오버플로우가 발생할 수 있습니다. 특히 a 와 b가 둘다 양수이고 매우 큰 값일 경우 정수범위를 초과할 수 있습니다.
        • 해결 방법 : 정수 오버플로우에 대비해 이 연산을 수행할 때 주의해야 합니다. C++ 에서 a와 b가 모두 int형 이라면, 이들을 long long 같은 더 큰 자료형으로 변환한 후 계산하는 방법이 있습니다
  4. 개선점 : 
    1. 데이터 구조:
      • 나 : vector를 사용하여 각 작업의 완료 일수를 저장하고 이후 이 벡터를 순회하면서 배포 그룹을 계산함.
      • 제안 : queue를 사용하여 완료 일수를 저장하고, 큐에서 하나씩 꺼내면서 배포 그룹을 계산합니다.
        • 비교 : 벡터와 큐는 이 문제에서 거의 동일한 역할을 수행합니다. 그러나 큐를 사용하면 순차적으로 처리된다는 의도가 좀 더 명확해집니다.

 

큐를 사용한 코드 :

#include <vector>
#include <queue>

using namespace std;

vector<int> solution(vector<int> progresses, vector<int> speeds) {
    vector<int> answer;
    queue<int> daysQueue;
    
    // 각 작업의 완료 날짜 계산
    for (size_t i = 0; i < progresses.size(); ++i) {
        int days = (100 - progresses[i] + speeds[i] - 1) / speeds[i]; // 올림 계산
        daysQueue.push(days);
    }

    while (!daysQueue.empty()) {
        int deployDay = daysQueue.front(); // 첫 번째 작업의 완료 날짜
        daysQueue.pop();
        
        int count = 1; // 배포할 작업 수

        // 다음 작업들이 같이 배포될 수 있는지 확인
        while (!daysQueue.empty() && daysQueue.front() <= deployDay) {
            ++count;
            daysQueue.pop();
        }
        
        answer.push_back(count); // 배포할 작업 수를 결과에 추가
    }
    
    return answer;
}

'코드카타 > 코딩테스트' 카테고리의 다른 글

타겟 넘버  (0) 2024.08.16
더 맵게  (0) 2024.08.15
같은 숫자는 싫어  (0) 2024.08.15
가장 큰 수  (0) 2024.08.15
베스트앨범  (0) 2024.08.15