※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 1744번 문제인 수 묶기이다.
문제는 아래 링크를 확인하자.
1744번: 수 묶기
길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에
www.acmicpc.net
이 문제는 주어진 숫자를 둘씩 짝을 지어 곱해 더하거나 그냥 더해 최댓값을 얻는 것이 목표이다.
이때, 주어지는 숫자에는 양수도 음수도 있음에 유의하여야 한다.
이 문제의 풀이를 구상할 때 신경써야하는 점을 살펴보자.
1) 두 음의 정수의 곱은 양의 정수가 된다. 따라서 음의 정수가 여러 개 있다면 가장 작은(절댓값이 가장 큰) 두 수를 곱해 더해줘야한다.
2) 위와 같이 묶고 음의 정수가 1개 남았을 때 남은 정수 중 0이 있다면 음의 정수를 더하는 것보다는 음수와 0을 곱해 더해야 한다. 남는 0이 있다면 그냥 더해주면 된다. (음의 정수끼리 곱하여 양수를 만드는 것이 더 이득이기 때문)
3) 양의 정수들은 큰 수 2개끼리 묶어서 곱해나가야한다. 단, 1은 다른 수와 곱하지 말고 따로 더해야 한다.
위 내용을 신경쓰면서 다음과 같은 알고리즘을 구상하였다.
1) 입력을 받아 배열을 만든 후 크기순으로 정렬한다.
2) 배열의 왼쪽서부터 양이 아닌 정수를 크기순으로, 짝을 지을 수 없을 때까지 둘씩 묶어 곱해 더한다.
2-1) 짝을 짓지 못하고 남은 수는 그냥 더해준다.
3) 배열의 오른쪽서부터 1보다 큰 양의 정수를 크기순으로, 짝을 지을 수 없을 때까지 둘씩 묶어 곱해 더한다.
3-1) 짝을 짓지 못하고 남은 수는 그냥 더해준다.
4) 남은 수는 1 뿐이다. 1의 개수를 더해준다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <algorithm>
using std::sort;
using std::cin;
using std::cout;
int nums[10000];
int main()
{
std::ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
int x;
int cntone = 0;
for (int i = 0;i < n;i++) {
cin >> x;
nums[i] = x;
if (x == 1) cntone++; // 1의 개수를 미리 세둔다
}
sort(nums, nums + n);
int ans = 0;
int leftpt = 0; // 배열의 왼쪽부터 살필 포인터
int rightpt = n - 1; // 배열의 오른쪽부터 살필 포인터
if (n == 1) cout << nums[0]; // 예외처리 - 배열의 크기가 1인 경우
else {
while (nums[leftpt + 1] < 1) { // 양이 아닌 정수들을 크기순으로 짝지어 곱해 더하기
ans += nums[leftpt] * nums[leftpt + 1];
leftpt += 2;
if (leftpt == n - 1 or leftpt == n) break; // 예외처리 - 배열의 모든 정수가 음수인 경우
}
if (leftpt < n) { // 짝을 짓지 못하고 남은 양이 아닌 정수를 더하기
if (nums[leftpt] < 1) ans += nums[leftpt];
}
while (nums[rightpt - 1] > 1) { // 1보다 큰 양의 정수들을 크기순으로 짝지어 곱해 더하기
ans += nums[rightpt] * nums[rightpt - 1];
rightpt -= 2;
if (rightpt == 0 or rightpt == -1) break; // 예외처리 - 배열의 모든 정수가 양수인 경우
}
if (rightpt >= 0) { // 짝을 짓지 못하고 남은 1보다 큰 양의 정수를 더하기
if (nums[rightpt] > 1) ans += nums[rightpt];
}
ans += cntone; // 1을 개수만큼 더해주기
cout << ans;
}
return 0;
}
'BOJ' 카테고리의 다른 글
[BOJ 1300 // C++] K번째 수 (0) | 2021.01.11 |
---|---|
[BOJ 1253 // C++] 좋다 (0) | 2021.01.10 |
[BOJ 6615 // C++] 콜라츠 추측 (0) | 2021.01.08 |
[BOJ 5393 // C++] 콜라츠 (0) | 2021.01.07 |
[BOJ 7453 // C++] 합이 0인 네 정수 (0) | 2021.01.06 |