문제 |
2798번: 블랙잭
첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다. 합이 M을 넘지 않는 카드 3장
www.acmicpc.net
코드 1 |
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<int> v(n);
for (int &i: v) {
cin >> i;
}
int mx = -1;
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
for (int k = j + 1; k < n; k++) {
int sum = v[i] + v[j] + v[k];
if (sum <= m && sum > mx) mx = sum;
}
}
}
cout << mx;
return 0;
}
설명 |
그냥 3중 for문을 돌리면 된다...
시간복잡도는 O(n^3)으로 매우 느리지만, n의 최댓값이 100에 불과하기 때문에 가능하다.
코드 2 |
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n, m;
vector<int> v;
// value 이하인 최댓값을 찾는다.
int binarySearch(int low, int high, int value) {
if (v[high] <= value) return v[high];
int res = -1;
while (low <= high) {
int mid = (low + high) / 2;
if (v[mid] == value) return value;
if (v[mid] < value) {
res = v[mid];
low = mid + 1;
} else {
high = mid - 1;
}
}
return res;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
v = vector<int>(n);
for (int &i: v) {
cin >> i;
}
sort(v.begin(), v.end());
int mx = -1;
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n - 1; j++) {
int sum = v[i] + v[j];
if (sum >= m) continue;
sum += binarySearch(j + 1, n - 1, m - sum);
if (sum > mx) mx = sum;
}
}
cout << mx;
return 0;
}
설명 |
위의 코드에서 i, j를 구하는 과정은 그대로 두고 k를 이분탐색으로 구할 수 있다.
시간복잡도는 O(N^2log n)이 된다.
'PS > BOJ' 카테고리의 다른 글
[C++] BOJ (백준) 2839 : 설탕 배달 (0) | 2023.03.01 |
---|---|
[C++] BOJ (백준) 2805 : 나무 자르기 (0) | 2023.03.01 |
[C++] BOJ (백준) 2775 : 부녀회장이 될테야 (0) | 2023.02.28 |
[C++] BOJ (백준) 24901 : Binary Game 2 (0) | 2023.02.28 |
[C++] BOJ (백준) 2751 : 수 정렬하기 2 (0) | 2023.01.12 |