https://www.acmicpc.net/problem/11930
[필자 사고]
최소 외접원 문제이다. 이 문제만의 특이한 점은 구형태로 주어졌다는 점이다.
다만 구형태로 주어졌어도 하나의 변수만 는 것뿐 2차원에서 풀던것과 똑같이 풀면된다.
필자는 이번에 20000번의 iteration으로 설정했고 ratio 는 0.995로 갱신으로 설정해서 답을 구했다.
[코드 해설]
1. 입력 처리
- 먼저 NN개의 점의 개수를 입력받습니다.
- 각 점의 xx, yy, zz 좌표를 각각 세 개의 벡터 a, b, c에 저장합니다. 이 벡터들은 각각 모든 점의 xx, yy, zz 좌표를 담고 있어 이후 계산에서 활용됩니다.
2. 초기 중심점 계산
- 중심점을 구하기 위해 각 좌표의 평균값을 계산합니다.
- xx 좌표의 평균은 모든 점의 xx 좌표를 더한 후 점의 개수 NN으로 나눈 값입니다.
- yy와 zz 좌표도 동일한 방식으로 계산됩니다.
- 이렇게 계산된 평균값이 중심점의 초기 좌표로 설정됩니다. 이 초기값은 중심점의 대략적인 위치를 빠르게 설정하는 데 사용됩니다.
3. 중심점 최적화
- 초기 중심점에서 시작해 모든 점과의 최대 거리가 최소가 되는 방향으로 중심점을 반복적으로 조정합니다.
- 중심점 조정 과정은 다음과 같습니다:
- 현재 중심점에서 각 점과의 거리를 계산합니다.
- 가장 먼 거리에 있는 점을 찾습니다.
- 중심점을 이 가장 먼 점의 방향으로 이동시킵니다. 이때 이동 거리는 점과의 거리의 일정 비율로 설정됩니다.
- 이동 비율은 반복이 진행될수록 점차 줄어듭니다. 이를 통해 초기에는 큰 단위로 이동하며 대략적인 중심점을 찾고, 반복이 진행될수록 미세 조정이 이루어지게 됩니다.
- 이 과정은 정해진 횟수(20,000번) 동안 반복됩니다.
[소스 코드]
#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
using namespace std;
int N;
vector<int> a;
vector<int> b;
vector<int> c;
double calculateDistance(double x1, double y1, double z1, double x2, double y2, double z2) {
return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2) + pow(z2 - z1, 2));
}
int main(void) {
cin >> N;
a.resize(N);
b.resize(N);
c.resize(N);
for (int i = 0; i < N; i++) {
cin >> a[i] >> b[i] >> c[i];
}
double x, y, z;
x = accumulate(a.begin(), a.end(), 0.0) / N;
y = accumulate(b.begin(), b.end(), 0.0) / N;
z = accumulate(c.begin(), c.end(), 0.0) / N;
double ratio = 0.1, maxDistance;
int maxIndex;
for (int iter = 0; iter < 20000; iter++) {
maxDistance = calculateDistance(a[0], b[0], c[0], x, y, z);
maxIndex = 0;
for (int k = 1; k < N; k++) {
double curDistance = calculateDistance(a[k], b[k], c[k], x, y, z);
if (curDistance > maxDistance) {
maxDistance = curDistance;
maxIndex = k;
}
}
x += (a[maxIndex] - x) * ratio;
y += (b[maxIndex] - y) * ratio;
z += (c[maxIndex] - z) * ratio;
ratio *= 0.995;
}
cout.precision(2);
cout << fixed;
cout << maxDistance << endl;
return 0;
}
'백준 > 수학' 카테고리의 다른 글
백준 10517 c++ "Radar Coverage" -PlusUltraCode- (0) | 2025.01.20 |
---|---|
백준 9158 c++ "Super Star" -PlusUltraCode- (0) | 2025.01.20 |
백준 13708 c++ "모든 점을 포함하는 원" -PlusUltraCode- (0) | 2025.01.20 |
백준 2389 c++ "세상의 중심에서..." -PlusUltraCode- (0) | 2025.01.20 |
백준 2626 c++ "헬기착륙장" -PlusUltraCode- (0) | 2025.01.20 |