Lv 0 . 연속된 수의 합

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

 

#include <string>
#include <vector>

using namespace std;

vector<int> solution(int num, int total) {
    vector<int> answer;
    
    int tmp=total/num;
    int a= tmp - (num%2==0? (num/2-1) :num/2);
    int i=0; 
    while(num--){
        answer.emplace_back(a+i);
        i++;
    }
    return answer;
}

가운데 수를 구하고, 갯수가 홀수면 완벽하게 가운데 수를 구할 수 있는 경우인데, 짝수면 가운데 수가 아니라 가운데에서 왼편에 있는 정수의 값이 나오기 때문에, 해당 경우들을 나누어서 등차가 1인 등비수열의 초항 a 를 구하는 형태를 달리해서 a를 구한뒤에, 

+1 씩 해나가면서 answer에 담는 형태로 코드를 작성하였다. 

 

다른 사람의 풀이를 보니, 대가 푼 방식처럼 푼 사람도 있었지만, 

#include <string>
#include <vector>

using namespace std;

vector<int> solution(int num, int total) {
    vector<int> answer;
    int sum = num * (num + 1) / 2;
    int start = (total - sum) / num + 1;

    for (int i = start; i < start + num; i++)
        answer.push_back(i);
    return answer;
}

이와 같은 풀이를 발견할 수 있었고, 이 풀이의 경우는, 

예를들어 3개 수의 합이 12라면, 

 

1 2 3 까지의 수의 합은 6이고, 이 값을  sum 이라 할때,  

total이 12가 되게 하는 수들을 생각해보면, 

 

3 4 5 인데, 이것을 start + p, start+ p + 1 , start+p + 2 이라 하면, 

이 세 수의 합은  total = 3* start + 3p + 3 이고, 이것에서 sum 이라는 수를 빼면,

위 수는 결국 시작 1과 주어진 세 수의 합에서의 초항과의 차이인 q의 num의 갯수배 차이가 나므로, 그걸 num로 나누면

초항 start 값이 나오게 된다. 

그렇게 초항을 구했으므로, 

for(int i= start; i<start + num; i++)

  answer.push_back(i); 

형태의 반복문으로 넣어주기만 하면 끝이다. 

 

수학적으로 등차수열에 대한 이해와, 간격이 벌어져있는 것에 대한 이해, 그리고 그 간격만큼이 발생하는 차이값을 제대로 이해한다면

아래의 풀이가 훨씬 더 보기 편하고 이해하기 좋은 형태의 코드라고 생각된다.

 위의 내 풀이는 c++에서 int의 값이 잘려서 어떻게 담기는지에 대한 이해가 필요한 부분이라

오히려 만약 등차수열의 합에 대해서 더 이해할 수 있는 상황이라면 아래와 같은 풀이가 더 좋을 것이라 생각된다. 

 

'알고리즘 > 프로그래머스' 카테고리의 다른 글

코딩테스트 입문 Lv 0 100문제 해결 완료.  (0) 2023.10.12
Lv 0. 다음에 올 숫자  (0) 2023.10.12
Lv 0. 종이 자르기  (0) 2023.10.12
Lv 0. 문자열 밀기.  (0) 2023.10.12
Lv 0. k의 개수  (0) 2023.10.12
  Comments,     Trackbacks