수학과의 좌충우돌 프로그래밍

[C++] BAEKJOON 1744 수 묶기 본문

알고리즘/C++

[C++] BAEKJOON 1744 수 묶기

ssung.k 2019. 9. 15. 00:02

https://www.acmicpc.net/problem/1744

 

1744번: 수 묶기

길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에 상관없이 묶을 수 있다. 하지만, 같은 위치에 있는 수(자기 자신)를 묶는 것은 불가능하다. 그리고 어떤 수를 묶게 되면, 수열의 합을 구할 때 묶은 수는 서로 곱한 후에 더한다. 예를 들면, 어떤 수열이 {0, 1, 2, 4, 3, 5}일 때, 그냥 이 수열

www.acmicpc.net

그리디 알고리즘 을 이용해서 문제를 해결하였습니다.

합이 최대가 되기 위해서는 절대값이 큰 수끼리 묶어주어야 합니다. 양수에 대해서는 큰 수 끼리, 음수에 대해서는 작은 수끼리 우선적으로 곱해줍니다. 양수와 음수에 대해서 따로 받아 정렬을 한 후 두 개씩 곱해주며 더해주었습니다.

구현도 구현이지만 예외사항들을 처리해주는게 까다로웠습니다.

  • 1 이 2개 이상인 경우

    1 이 2개 이상인 경우 위와 같은 알고리즘을 적용할 시 1과 1을 곱해서 더해주게 됩니다. 그러면 따로 더해주는 것 보다 오히려 작게 되므로 1은 따로 세주어서 1의 개수 만큼 더해줍니다.

  • 0 이 존재하고 음수가 홀수 개인 경우

    음수가 홀수개라면 2개씩 짝을 짓고 하나가 남게 됩니다. 이 때 0이 존재한다면 0을 곱해서 음수를 없애주도록 합니다.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int compare(int a, int b){
    if (a>b) return true;
    else return false;
}

int main(int argc, const char * argv[]) {
    
    vector <int> plus;
    vector <int> minus;
    
    int N;
    cin >> N;
    
    int answer = 0;
    int zeroNum = 0;
    int oneNum = 0;
    
    for (int i=0;i<N;i++){
        int input;
        cin >> input;
        if (input == 1) oneNum++;
        else if (input == 0) zeroNum++;
        else if (input > 0) plus.push_back(input);
        else minus.push_back(input);
    }
    // 내림차순
    sort(plus.begin(), plus.end(), compare);
  	// 오름차순
    sort(minus.begin(), minus.end());
    
    answer += oneNum;
    
    plus.push_back(1);
    minus.push_back(1);
    
    for (int i=0;i<plus.size()-1;i+=2){
        answer += plus[i] * plus[i+1];
    }
    for (int i=0;i<minus.size()-1;i+=2){
        answer += minus[i] * minus[i+1];
    }
    // minus가 홀수 개 이고 0이 있을 때 하나를 0이랑 곱해 상쇄
    if (minus.size()%2==0 && zeroNum >= 1){
        answer -= minus[minus.size()-2];
    }
    
    cout << answer << "\n";

    return 0;
}

 

'알고리즘 > C++' 카테고리의 다른 글

[C++] BAEKJOON 10610 30  (0) 2019.09.15
[C++] BAEKJOON 2875 대회 or 인턴  (0) 2019.09.15
[C++] BAEKJOON 1541 잃어버린 괄호  (0) 2019.09.14
[C++] BAEKJOON 1931회의실 배정  (0) 2019.09.14
[C++] BAEKJOON 10830 행렬 제곱  (0) 2019.09.10
Comments