HDU1007 --- Job title

Server collapse, not data backup, back garden blog

HDU1007

Meaning of the questions:
to give you some points on a coordinate plane, let you figure out this pile of points, half of the number of shortest distance two points, the distance?


Solution:
data \ (the n-6 = 10 ^ \) , if we enumerate each point, then, it is clear that the complexity will reach \ (the n-^ 2 \) , this will certainly timeout.


Consider using divide and conquer.

  1. First, we follow the point \ (x \) axis coordinates from small to large
  2. Select a midpoint \ (MID \) , all the current is divided into right and left points \ ((1, mid), (mid + 1, n) \)
    • The results can now be launched only three cases
      • Two points are on the left
      • Two points are on the right
      • One on the left, one on the right
  3. For results \ (1 \) and the result \ (2 \) we can find a recursive, recursion boundary when the current number of points is \ (2 \) or (3 \) \ , we can directly calculate the results .
    We have got so \ (Lmin \) and \ (Rmin \) .

Next, processing the third result .

As we previously come to \ (Lmin \) and \ (Rmin \) , thereby obtaining \ (DIS = min (Lmin, Rmin) \) .

If you want to verify the results of the third, it must be connected by a point to the right of the left point, and the shortest distance, so we naturally choose \ (mid \) points.

Next, at present all points selected and \ (MID \) point \ (X \) axis distance is no greater than \ (DIS \) in all points. (If even \ (X \) axis is greater than the distance dis, count \ (Y \) axis distance farther only)

The chosen point by \ (\ Y) axis coordinates from small to large, and these points can be enumerated.

Intermediate may further prune, if \ (V \) from the point has arrived greater than \ (DIS \) , then the next point can be replaced.


Additional knowledge (are interested can learn)

In just the last step of the enumeration, in Introduction to Algorithms we have explained.

We will click on it, these points are in a natural \ (X \) axis distance \ (2 * dis \) of a region.

picture

Select a point as a base point , and the distance is less than his (DIS \) \ other points, natural \ (Y \) axis distance is not greater than \ (DIS \)
So we for each point can draw a region, and this both sides in the region up to 4 points, the sum of 8 points.

picture

Because if any of you around while more than a point, does not meet before obtaining \ (Lmin \) .

That is at best only an enumeration of each point eight times.

#include <bits/stdc++.h>
//freopen("in.txt", "r", stdin);

using namespace std;
typedef double dou;
typedef long long ll;
typedef pair<ll, ll> pii;

#define M 200050
#define inf 0x3f3f3f3f
#define mod 998244353
#define W(a) while(a)
#define lowbit(a) a&(-a)
#define left k<<1
#define right k<<1|1
#define ms(a,b) memset(a,b,sizeof(a))
#define debug(a) cout<<#a<<" == "<<a<<endl
#define false_stdio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

int n;
struct Data {
    dou x;
    dou y;
}node[M];

bool cmpx(Data &a, Data &b) { return a.x < b.x; }
bool cmpy(Data &a, Data &b) { return a.y < b.y; }

dou dis(Data& a, Data &b) { return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); }

dou solve(int L, int R) {
    if (L + 1 == R)return dis(node[L], node[R]);//如果目前只有两个点
    if (L + 2 == R)return min(dis(node[L], node[L + 1]), min(dis(node[L], node[R]), dis(node[L + 1], node[R])));//如果目前只有三个点
    int mid = L + R >> 1;
    dou ans = min(solve(L, mid), solve(mid + 1, R));//递归求左右两边最小距离

    //选点
    vector<Data>tmp;
    for (; L <= R; L++) {
        if (fabs(node[mid].x - node[L].x) <= ans) {
            tmp.push_back(node[L]);
        }
    }
    sort(tmp.begin(), tmp.end(), cmpy);//按y坐标排序

    //枚举点
    for (int i = 0; i < tmp.size(); i++) {
        for (int j = i + 1; j < tmp.size(); j++) {
            if (tmp[j].y - tmp[i].y >= ans)break;
            ans = min(ans, dis(tmp[i], tmp[j]));
        }
    }
    return ans;
}

int main() {
    false_stdio;//HDU貌似关闭同步cin还是慢,所以还是用scanf了
    W(scanf("%d", &n) != EOF && n) {
        for (int i = 1; i <= n; i++) scanf("%lf%lf", &node[i].x, &node[i].y);
        sort(node + 1, node + n + 1, cmpx);//按x坐标排序
        printf("%.2lf\n", solve(1, n) / 2.0);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/caibingxu/p/12536369.html