백준 문제/그리디

[백준] 1744번 수 묶기

dubu0721 2024. 11. 15. 17:17

문제: 1744번: 수 묶기

 

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip> // setprecision을 사용하기 위한 헤더

using namespace std;

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int n;
	cin >> n;
	
	priority_queue<int, vector<int>, greater<int>> nums;
	for (int i = 0; i < n; i++) {
		int tmp;
		cin >> tmp;
		nums.push(tmp);
	}

	int sum = 0;
	while (nums.size() >= 2) {
		bool flag = nums.size() % 2 == 0 ? true : false; // nums 의 요소 개수가 짝수인지 홀수인지 판단..
		int num1 = nums.top();
		nums.pop();
		int num2 = nums.top();
		nums.pop();

		if (num1 < 0 && num2 < 0) {
			sum += num1 * num2;
		}
		else if (num1 < 0 && num2==0) {
			sum += num1 * num2;
		}
		else if (num1 < 0 && num2 > 0) {
			// num1 단독으로 더하고 num2 는 다시 넣어
			sum += num1;
			nums.push(num2);
		}
		else if (num1 == 0 && num2 == 0) {
			sum += 0;
		}
		else if (num1 == 0 && num2 > 0) {
			sum += num2;
		}
		else if (num1 > 0 && num2 > 0) {
			if (num1 == 1 && num2 == 1)
				sum += 2;
			else if (num1 == 1 && num2 > 1) {
				sum += num1;
				nums.push(num2);
			}
			else {
				// 홀수일때, num1 만 먼저 더함
				if (flag == false) {
					sum += num1;
					nums.push(num2);
				}
				else {
					sum += num1 * num2;
				}
			}
		}
	}
	while (!nums.empty()) {
		sum += nums.top();
		nums.pop();
	}
	cout << sum << "\n";


	return 0;
}

 

그냥 수들을 정렬만 시켜놓으면 간단하게 해결되는 문제였다.

 

수를 정렬시키기 위해서 나는 최소힙을 이용했다.

 

그렇다면 이제 수가 가장 커지는 경우를 생각을 해봐야 한다.

1. 음수*음수=양수 이므로 최소힙에서 빼낸 두 값이 모두 음수라면 둘을 묶는다.

2. 차례로 음수, 0의 값이 뽑혔다면 음수는 없애버리는게 좋으므로 둘을 묶는다.

3. 차례로 음수, 양수의 값이 뽑혔다면 이 둘을 곱했을 때 좋은 점이 없으므로 둘을 묶지 않는다.

4. 차례로 0, 0의 값이 뽑혔다면 둘을 묶는다.

5. 차례로 0, 양수의 값이 뽑혔다면 이 둘을 곱했을 때 좋은 점이 없으므로 둘을 묶지 않는다.

6. 차례로 양수, 양수의 값이 뽑혔을 경우(세가지 경우로 나뉨)

  • 1, 1이 뽑힌 경우: 둘을 묶는다.
  • 1, 1보다 큰 양수가 뽑힌 경우: 1이랑 다른 양수랑 곱하면 1을 손해보게 되니까 둘을 묶지 않는다.
  • 둘 다 1보다 큰 양수일 경우(두가지 경우로 나뉨)
    • 큐의 요소의 개수가 짝수였을 경우: 큐의 요소의 개수가 짝수라면 그냥 차례로 둘을 묶는다.
    • 큐의 요소의 개수가 홀수였을 경우: 두 수를 뽑기 전 큐의 요소가 홀수개였다면, 이 둘을 묶지 않는다. 둘을 곱했을 때 수가 가장 크도록 해야하는데 이게 가장 크도록 하려면 맨 뒤에 요소 2개씩 묶어야 함. 짝수일때는 어차피 짝이 맞으니까 상관 안 했는데 홀수일 경우는 앞에서부터 2개씩 묶으면 맨 마지막에 가장 큰 수가 남으므로 손해. 즉, 뒤부터 두개씩 짝을 묶는 것처럼 하기 위해서 맨 처음에 뺀 거는 따로 더해주고 다음부터 다시 2개씩 묶음..

 

음.. 어렵지는 않았는데 뽑힌 수가 둘 다 1인 경우를 잘 생각하지 못해서 처음에 틀렸다. 그래도 빨리 풀어서 기분 좋았다. ^0^

  

'백준 문제 > 그리디' 카테고리의 다른 글

[백준] 8980번 택배  (0) 2024.12.05
[백준] 1439번 뒤집기  (0) 2024.12.04
[백준] 11000 강의실 배정  (3) 2024.11.10
[백준] 1946번 신입 사원  (0) 2024.11.06
[백준] 12904번 A와 B  (0) 2024.11.05