Time Limit: 1000 ms Memory Limit: 256 MB
Total Submission: 78 Submission Accepted: 8
Total Submission: 78 Submission Accepted: 8
Judge By Case
Description
给定平面上n个点,找出其中的一对点的距离,使得这n个点的所有点对中,该距离为所有点对中最小的。
Input
第一行:n;2≤n≤60000;
接下来n行:每行两个整数:x y,表示一个点的行坐标和列坐标,中间用一个空格隔开。
接下来n行:每行两个整数:x y,表示一个点的行坐标和列坐标,中间用一个空格隔开。
Output
仅一行,一个实数,表示最短距离,精确到小数点后面4位。
Sample Input
Original | Transformed |
3 1 1 1 2 2 2
3[EOL] 1[SP][SP]1[EOL] 1[SP][SP]2[EOL] 2[SP][SP]2[EOF]
Sample Output
Original | Transformed |
1.0000
1.0000[EOF]
这题可能最大的收获是发现了加
cin.tie(0);
cin.sync_with_stdio(false);
的情况下scanf和cin不能混用
题解如下
#include<cstdio>
#include<iostream>
#include<ctime>
#include<algorithm>
#include<cmath>
//#define DEBUG
using namespace std;
const int maxn = 100000;
struct point {
double x, y;
}a[maxn + 5], b[maxn + 5];
double val;
bool comp_x(point a, point b) {
if (a.x == b.x)
return a.y < b.y;
else
return a.x < b.x;
}
bool comp_y(point a, point b) {
if(a.y==b.y)
return a.x < b.x;
else
return a.y < b.y;
}
double dis(point a, point b) {
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
double solve(int l, int r) {
if (r - l == 1)
return dis(a[l], a[r]);
if (r - l == 2) {
double d1= dis(a[l], a[l+1]);
double d2 = dis(a[l], a[r]);
double d3 = dis(a[l+1], a[r]);
return min(d1, min(d2, d3));
}
int mid = (l + r) / 2;
double disl = solve(l, mid);
double disr = solve(mid + 1, r);
val = min(disl, disr);
int k = 0;
for (int i = l; i <= r; i++) {
if (fabs(a[i].x - a[mid].x) < val) {
b[k].x = a[i].x;
b[k].y = a[i].y;
k++;
}
}
sort(b, b + k, comp_y);
for (int i = 0; i < k - 1; i++) {
for (int j = i + 1; j < k; j++) {
if (b[j].y - b[i].y < val) {
if (dis(b[j], b[i]) < val) {
val = dis(b[j], b[i]);
}
}
else break;
}
}
return val;
}
int main() {
cin.tie(0);
cin.sync_with_stdio(false);
#ifdef DEBUG
int START = clock();
freopen("Text.txt", "r", stdin);
#endif
int n;
cin >> n;
for (int i = 0; i < n; i++) {
//scanf("%lf %lf", &a[i].x, &a[i].y);
cin >> a[i].x >> a[i].y;
}
sort(a, a + n, comp_x);
printf("%.4lf\n", solve(0, n - 1));
#ifdef DEBUG
printf("Time:%.3lf\n", (double)(clock() - START) / CLOCKS_PER_SEC);
#endif
return 0;
}