티스토리 뷰
문제 이해부터 해보자
수열 {0,1,2,4,3,5}가 들어왔을때
두 수를 묶거나 묶지 않을 수 있다
그리고 묶는 것은 중복되지 않는다
무슨소리냐면
예를들어 (1,2)를 묶었는데 (2,4)로 또 2를 중복시켜 묶을 수는 없다는 것이다
묶게되면 묶은 두 수 끼리 곱해서 더해지고
묶지 않으면 그냥 더해진다
{0,1,2,4,3,5}의 이 규칙을 통해
최댓값을 내는 경우는
0,1, {2,3}, {4,5}이다
그러면 0+1+(2*3)+(4*5)가 되어
27이 된다
다음은 테스트케이스를 분석해보자
-1
2
1
3
이 경우는
-1,1,(2,3)을 해주면
-1 + 1 + (2*3) = 6이 최댓값
0
1
2
4
3
5
(5,4), (3,2) 1,0
20+6+1=27
-1
-1
-1
0
1
(-1,0), 1
0+1=1
1
1
1+1 = 2
다른 경우는 보통 큰 수 끼리 묶어서 곱하는데
그렇지 않은 경우가 예외적으로 있다
그래서 나는
음수를 받는 벡터 하나
양수를 받는 벡터 하나
0을 받는 벡터 하나
총 세개를 만들어서
정렬시키고
2개씩 묶어서 더해주다가
마지막으로 음수, 양수가 한개남았을때 예외적으로 처리해 주었다
예를들어
-6 0 6이 나오면
-6, (0,6) 보다
(-6,0) 6이 더 크다
음수와 0이 남은 경우는
묶어주면 0이돼서 더했을때 최댓값이 된다
그리고
0 6이 남으면(0,양수)
묶어주지 않아야한다
-2,6이 남아도(음수, 양수)
묶어주지 않아야한다
이런식으로
큰 수 부터 2개씩 차례로 묶어주다가
마지막으로 1개씩 남는 상황에서
일일히 처리를 해주었다
묶어줄지 더해줄지
나의 코드이다
#include <iostream>
#include <vector>
#include <algorithm>
#define MAX(a,b) a>b ? a : b
using namespace std;
bool cmp(int a, int b) {
return a > b;
}
int main() {
int n;
long long int count = 0;
cin >> n;
vector<int> plus;
vector<int> zero;
vector<int> minus;
for (int i = 0; i < n; i++) {
int temp;
cin >> temp;
if (temp == 0) {
zero.push_back(temp);
}
else if (temp > 0) {
plus.push_back(temp);
}
else {
minus.push_back(temp);
}
}
sort(minus.begin(), minus.end());
sort(plus.begin(), plus.end(),cmp);
/*for (int i = 0; i < plus.size(); i++) {
cout << "plus" << endl;
cout << plus[i] << endl;
}
for (int i = 0; i < minus.size(); i++) {
cout << "minus" << endl;
cout << minus[i] << endl;
}
for (int i = 0; i < zero.size(); i++) {
cout << "zero" << endl;
cout << zero[i] << endl;
}
*/
while (true) {
if (plus.size() >= 2) {
int prod, sum,max;
sum = plus[0] + plus[1];
prod = plus[0] * plus[1];
max = MAX(sum, prod);
count += max;
plus.erase(plus.begin());
plus.erase(plus.begin());
}
if (minus.size() >= 2) {
int prod = minus[0] * minus[1];
count += prod;
minus.erase(minus.begin());
minus.erase(minus.begin());
}
if (minus.empty() && plus.empty())
break;
if (plus.size() <= 1 && minus.size() <= 1) {
bool plusfull = !plus.empty();
bool minusfull = !minus.empty();
bool zerofull = !zero.empty();
//case1 plus o zero x minus x
//case2 plus x zero x minus o o가 하나인 경우
//case3 plus x zero 0 minus x
//case4 plus o zero o minus x o가 두개인 경우
//case5 plus o zero x minus o
//caes6 plus x zero o minus o
//case7 plus o zero o minus o //o가 세개나 0개인경우
//case8 plus x zero x minus x
if (plusfull && !zerofull && !minusfull) {
count += plus[0];
plus.erase(plus.begin());
}
else if (!plusfull && !zerofull && minusfull) {
count += minus[0];
minus.erase(minus.begin());
}
else if (!plusfull && zerofull && !minusfull) {
//
}
else if (plusfull && zerofull && !minusfull) {
count += plus[0];
plus.erase(plus.begin());
}
else if (plusfull && !zerofull && minusfull) {
count += plus[0] + minus[0];
plus.erase(plus.begin());
minus.erase(minus.begin());
}
else if (!plusfull && zerofull && minusfull) {
count += minus[0] * 0;
minus.erase(minus.begin());
}
else if (plusfull && zerofull && minusfull) {
count += (0 * minus[0]) + plus[0];
plus.erase(plus.begin());
minus.erase(minus.begin());
}
else if (!plusfull && !zerofull && !minusfull) {
//
}
}
}
cout << count;
return 0;
}
코드는 내가 생각해도 못짠거같은데
다른 아이디어가 떠오르지 않아서
근성으로 했다
아무튼 이 문제의 핵심은
2개씩 묶어주다가
1개가남으면
그 상황에서 어떻게 할것인가
양수와 0이남으면 더해주고
음수와 0이남으면 묶어주어야한다
양수와 음수가 남으면 더해주어야한다
'코딩 테스트 > 백준' 카테고리의 다른 글
백준 11279 최대 힙 c++ (0) | 2022.05.22 |
---|---|
백준 17087 숨바꼭질6 c++ 유클리드 호제법 (0) | 2022.02.22 |
백준 1931 회의실 배정 c++ (0) | 2022.02.20 |
백준 6588 c++ 골드바흐의 추측 (0) | 2022.02.16 |
퀵 정렬(Quick Sort) (0) | 2022.01.23 |
- Total
- Today
- Yesterday
- 데이터베이스
- authorization_code
- 오픈소스
- SQL
- CSS
- DML
- git commit 수정
- SpringBoot
- 2024인프콘
- 인프콘2024
- 클로아
- kloa
- git
- javascript
- 우분투
- git 예전 커밋 수정
- oauth2.0
- Android Studio
- html
- infcon 2024
- oauth
- html #웹 #웹사이트 #플레이리스트
- authorization code
- 데이터 3법
- bfs
- DDL
- 로스트아크 캐릭터
- 데이터3법
- 리눅스
- 프로그래머스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |