※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 16207번 문제인 직사각형이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/16207
16207번: 직사각형
길이가 5, 6, 6, 6인 막대 중에서 길이가 6인 막대 하나의 길이를 5로 줄여 넓이가 30인 직사각형을 만들 수 있다. 그 다음, 길이가 3, 4, 4, 4인 막대 중에서 길이가 4인 막대 하나의 길이를 3으로 줄여
www.acmicpc.net
가지고 있는 막대들을 긴 막대부터 살피면서 직사각형의 마주보는 두 변의 길이로 사용할 수 있는 막대를 greedy하게 짝지어나가자. (이미 짝에 사용된 막대를 다른 짝에 넣을 수는 없다.) 그리고 길이가 긴 막대짝부터 둘씩 묶어나가 직사각형을 구성해 문제를 해결하자.
이것이 최선의 전략이 됨은 어렵지 않게 증명할 수 있으므로 그 증명은 생략한다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
int N;
vector<int> vec;
vector<int> pvec;
ll ans;
ll old = 1000000007;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
while (N--) {
int x; cin >> x;
vec.emplace_back(x);
}
sort(vec.begin(), vec.end());
while (!vec.empty()) {
ll cur = vec.back(); vec.pop_back();
if (old == cur || old == cur + 1) {
pvec.emplace_back(cur);
old = 1000000007;
}
else old = cur;
}
reverse(pvec.begin(), pvec.end());
while (pvec.size() > 1) {
ll tmp = pvec.back(); pvec.pop_back();
ans += tmp * pvec.back(); pvec.pop_back();
}
cout << ans;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 22487 // C++] Do use segment tree (0) | 2023.09.16 |
---|---|
[BOJ 16206 // C++] 롤케이크 (0) | 2023.09.15 |
[BOJ 16210 // C++] DSHS Bank (0) | 2023.09.13 |
[BOJ 16209 // C++] 수열 섞기 (0) | 2023.09.12 |
[BOJ 25367 // C++] 너무 시시했다 (0) | 2023.09.11 |