문제 링크: https://www.acmicpc.net/problem/1007
문제가 조금 복잡한데요 풀이는 그렇게 어렵지 않은 문제입니다.
일단 입력으로 평면상의 점의 좌표가 주어집니다. 벡터 크기만 쓸거니까 (x, y), 아니면 (y, x) 뭐든 상관 없습니다.
그 다음, 이 점들을 모두 사용해서 벡터를 만든 뒤 벡터의 합의 길이 중 최소값을 구하는 것이 문제입니다. 벡터의 합은 x좌표는 x좌표끼리, y좌표는 y좌표끼리 더한 것이 됩니다.
점의 개수가 20개 이하이기 때문에 브루트포스로 모든 조합을 만들어보면 됩니다.
점을 절반씩, 한쪽은 from, 한쪽은 to로 나눕니다. 그 다음 ((from의 x좌표 합 - to의 x좌표 합), (from의 y좌표 합 - to의 y좌표 합)) 이 벡터의 크기를 구하면 됩니다.
절반씩 나눌 때 브루트포스로 조합을 만들어보면 되겠죠. 벡터의 크기는 원점에서 (x, y)까지의 거리를 구하면 됩니다
처음에 문제를 대충 읽었을 때 입력으로 벡터가 주어지고 두 벡터의 합이 최소가 되는 경우를 출력하는 줄 알고 O(N^2) 알고리즘으로 후다닥 풀어봤는데 역시나 아니었습니다. 문제를 좀 잘 읽어봐야겠습니다.
#pragma GCC optimize ("Ofast")
#define _CRT_SECURE_NO_WARNINGS
#define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr double sq(double a) { return a * a; }
// 벡터의 크기
// (0, 0) -> (x, y)
inline double dst(int x, int y) {
return sqrt(sq(y) + sq(x));
}
vector<pair<int, int>> vp; // x, y
ll x_sum, y_sum;
double min_sum;
void bruteforce(int n, vector<int>& picked, int toPick) {
if (toPick == 0) {
ll partial_x = 0, partial_y = 0;
for (auto& c : picked) {
partial_x += vp[c].first;
partial_y += vp[c].second;
}
ll diff_x = partial_x - (x_sum - partial_x),
diff_y = partial_y - (y_sum - partial_y);
min_sum = min(min_sum, dst(diff_x, diff_y));
return;
}
int smallest = picked.empty() ? 0 : picked.back(); // 오름차순
for (int i = smallest + 1; i < n; ++i) {
picked.push_back(i);
bruteforce(n, picked, toPick - 1);
picked.pop_back();
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
x_sum = 0, y_sum = 0;
min_sum = 1e9;
vp.resize(n);
for (auto it=vp.begin(); it!=vp.end(); ++it) {
cin >> it->first >> it->second;
x_sum += it->first;
y_sum += it->second;
}
vector<int> picked;
bruteforce(n, picked, n / 2);
cout << setprecision(7) << fixed << min_sum << '\n';
}
return 0;
}
반응형
'Online Judge > 백준' 카테고리의 다른 글
[백준][C++] 17406: 배열 돌리기 4 (0) | 2020.07.29 |
---|---|
[백준][C++] 18891: 제21대 국회의원 선거 (0) | 2020.07.29 |
[백준][C++] 1173: 운동 (0) | 2020.07.27 |
[백준][C++] 9935: 문자열 폭발 (0) | 2020.07.27 |
[백준][C++] 2468: 안전 영역 (0) | 2020.07.26 |