hdu1007 平面最近点对(暴力+双线程优化)

 突发奇想,用双线程似乎可以优化一些暴力

比如说平面最近点对这个题目,把点复制成2份

一份按照x排序,一份按照y排序

然后双线程暴力处理,一份处理x,一份处理y

如果数据利用x递减来卡,那么由于双线程,它卡不住y

如果数据利用y递减来卡,那么卡不住x

这样暴力n^2就可以过了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct P
{
    int id;
    double x, y;
    bool operator <(const P& B)const { return x < B.x; }
}p[100050], p2[100050];
bool cmp(const P &A, const P &B)
{ return A.y < B.y; }
double dis(P &A, P &B) { return (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y); }
int main()
{
    int n;
    while(cin>>n)
    {
        if(n == 0) break;
        double d = 1e8;
        for(int i = 1; i <= n; i++) scanf("%lf %lf", &p[i].x, &p[i].y), p2[i].x = p[i].x, p2[i].y = p[i].y;
        sort(p2+1, p2+1+n, cmp);
        sort(p+1, p+1+n);
        int tot1 = 0, tot2 = 100;
        for(int i1 = 2, i2 = 2, li1 = 1, li2 = 1; i1 <= n && i2 <= n; )
        {
            for(int j = li1; j >= 1; j--)
            {
                d = min(d, dis(p[i1], p[j]));
                if(((p[i1].x - p[j].x)*(p[i1].x - p[j].x) >= d)|| j == 1) { i1++; li1 = i1-1; break;}
                if(tot1 >= tot2) { tot1 += 200; li1 = j-1; break; } 
                tot1++;
            }
            for(int j = li2; j >= 1; j--)
            {
                d = min(d, dis(p2[i2], p2[j]));
                if(((p2[i2].y - p2[j].y)*(p2[i2].y - p2[j].y) >= d) || j == 1) { i2++; li2 = i2-1; break; }
                if(tot2 >= tot1) { tot2 += 200; li2 = j-1; break; }
                tot2++;
            }
        }
        printf("%.2f\n", sqrt(d)/2);
    }
}

 

posted @ 2016-12-02 20:19  Saurus  阅读(776)  评论(0编辑  收藏  举报