[C++][백준 BOJ]1744_수 묶기.
Algorithm/BaeKJoon

[C++][백준 BOJ]1744_수 묶기.

문제 번호

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

 

1744번: 수 묶기

길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에

www.acmicpc.net

 

 

 

알고리즘 분류

 그리디(greedy), 정렬

 

문제 풀이

 문제에서 주어진 수열을 오름차순으로 정렬한다. 합을 가장 크게 만드는게 목표이기 때문에 양수는 가장 큰 수 끼리

묶어서 더해야하고 음수는 가장 작은 수 끼리 묶어서 더해야한다. 그래서 양수부분의 합, 음수부분의 합을 구한다음 bool 형태의 visited 배열을 선언하여서  남은 수 들을 더해주기로하였다.

 

문제에서 주어진 수열을 오름차순으로 정렬한다.

sort(number.begin(), number.end());

양수부분의 합을 구한다.

// 양수 부분 구하기.
    for(int i=number.size()-1; i>0; i--)
    {        
        if( (!visitd[i] && !visitd[i-1]) && (number[i]>1 && number[i-1] >1) )
        {
            visitd[i] = visitd[i-1] = true;
            answer += number[i]*number[i-1];
        }
    }

음수부분의 합을 구한다.

// 음수 부분 구하기.
    for(int i=0; i<number.size()-1; i++)
    {
        if( (!visitd[i] && !visitd[i+1]) && (number[i]<=0 && number[i+1]<=0) )
        {
            visitd[i] = visitd[i+1] = true;
            answer += number[i]*number[i+1];
        }
    }

그리고 남겨진 수 들을 더해준다.

// 남겨진 수들 더하기.
      for(int i=0; i<number.size(); i++)
      {
          if( !visitd[i] )
              answer += number[i];
      }

전체 코드

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool visitd[10001] = {false};

long long Solution(vector<int> &number)
{
    long long answer=0;

    sort(number.begin(), number.end());
    
    // 양수 부분 구하기.
    for(int i=number.size()-1; i>0; i--)
    {        
        if( (!visitd[i] && !visitd[i-1]) && (number[i]>1 && number[i-1] >1) )
        {
            visitd[i] = visitd[i-1] = true;
            answer += number[i]*number[i-1];
        }
    }

    // 음수 부분 구하기.
    for(int i=0; i<number.size()-1; i++)
    {
        if( (!visitd[i] && !visitd[i+1]) && (number[i]<=0 && number[i+1]<=0) )
        {
            visitd[i] = visitd[i+1] = true;
            answer += number[i]*number[i+1];
        }
    }

    // 남겨진 수들 더하기.
    for(int i=0; i<number.size(); i++)
    {
        if( !visitd[i] )
            answer += number[i];
    }
    
    return answer;
}

void Insert(vector<int> &number, int N)
{
    for(int i=0; i<N; i++)
    {
        int num; cin >> num;
        number.push_back(num);
    }
}

int main()
{
    int N; cin >> N;
    vector<int> number;
    Insert(number,N);
    cout << Solution(number);

    return 0;
}

특이사항

 양수부분의 더할때 1은 다른수와 곱하는것보다 그냥 더해주는것이 더 큰 수 를 만들 수 있다.

문제에서 주어진 수열의 각 숫자들은 int 범위를 넘어가지 않지만 수열의 합은 int 범위를 넘어갈 수 있기 때문에

long long 타입으로 선언해주었다.

 

그리고 글쓰기 하면서 알았는데 visited 배열이름을 틀렸다.....

'Algorithm > BaeKJoon' 카테고리의 다른 글

[C++][백준 BOJ]16953_A->B.  (0) 2021.07.02
[C++][백준 BOJ]1080_행렬.  (0) 2021.07.02
[C++][백준 BOJ]1715_카드 정렬하기.  (0) 2021.07.01
[C++][백준 BOJ]1339_단어 수학  (0) 2021.06.29
[C++][백준 BOJ]1946_신입 사원.  (0) 2021.06.29