링크 :
https://www.acwing.com/problem/content/121/
질문의 의미 :
마지막 거점에 대한 리그의 패배, 제국의 후퇴와 후 전투.
, 강력한 방어 시스템에 여섯 파도 의존하는 것은 제국 공격의 연합을 물리 칠 수 있습니다.
무리의 몇 일 후, 연합 사령관 아서 마침내 제국의 방어 시스템이 에너지 공급에만 약점을 발견했습니다.
에너지 공급 시스템은 파괴 방어 시스템 고장의 원인이됩니다 N 원자력 발전소로 구성되어 있습니다.
일반 N의 거점으로 입력 할 에이전트를 보내, 그것은 에너지 역에 기습 공격을 개시 할 예정이다.
불행하게도 인해 독일 공군의 공격에, 그들은 예상 위치에 착륙하지 못했습니다.
경험 일반적으로, 아서 빨리 그가 계획 한 공격에 일정을 조정하는 데 필요한 깨달았다.
그는 지금 가장 알고 싶은이 최단 거리에있는 발전소의에서 어떤 에이전트입니다.
당신은 그를 최단 거리인지 알아내는 데 도움이 수 있습니까?
아이디어 :
중앙의 좌측 및 우측 최소의 처리 범위의 최소값의 중간의 좌우측, 모든 점을 계산하기 위해, N- 포인트 정렬 처리의 중간 점의 경우를 고려한다.
코드 :
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5+10;
struct Node
{
int x, y;
int op;
}a[MAXN], b[MAXN];
int n;
bool cmp(Node l, Node r)
{
if (l.x == r.x)
return l.y < r.y;
return l.x < r.x;
}
bool cmp1(Node l, Node r)
{
if (l.y == r.y)
return l.x < r.x;
return l.y < r.y;
}
double Getlen(Node l, Node r)
{
if (l.op == r.op)
return 1e9;
double dx = l.x-r.x, dy = l.y-r.y;
return sqrt(dx*dx+dy*dy);
}
double Sovle(int l, int r)
{
int mid = (l+r)/2;
if (l == r)
return 1e9;
if (r-l == 1)
return Getlen(a[l], a[r]);
double ans = min(Sovle(l, mid), Sovle(mid+1, r));
int cnt = 0;
for (int i = l;i <= r;i++)
{
if (a[i].x >= a[mid].x-ans && a[i].x <= a[mid].x+ans)
b[++cnt] = a[i];
}
sort(b+1, b+1+cnt, cmp1);
for (int i = 1;i <= cnt;i++)
{
for (int j = i+1;j <= cnt;j++)
{
if (b[j].y > b[i].y+ans)
break;
ans = min(ans, Getlen(a[i], a[j]));
}
}
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = 1;i <= n;i++)
scanf("%d%d", &a[i].x, &a[i].y), a[i].op = 0;
for (int i = n+1;i <= 2*n;i++)
scanf("%d%d", &a[i].x, &a[i].y), a[i].op = 1;
n *= 2;
sort(a+1, a+1+n, cmp);
printf("%.3lf\n", Sovle(1, n));
}
return 0;
}