zoukankan      html  css  js  c++  java
  • BZOJ 3053 The Closest M Points

     

    【题目分析】

        典型的KD-Tree例题,求k维空间中的最近点对,只需要在判断的过程中加上一个优先队列,就可以了。

    【代码】

        

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
     
    #include <set>
    #include <map>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <queue>
     
    using namespace std;
     
    #define maxn 1000005
    #define inf (0x3f3f3f3f)
    #define mk(a,b) make_pair(a,b)
     
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
     
    int D,rt,n,base,m,x;
     
    struct node{
        int d[6],mx[6],mn[6],l,r;
        int operator [] (int x) {return d[x];}
        void init() {for (int i=0;i<base;++i) d[i]=read();}
    }t[maxn],now;
     
    bool operator < (node a,node b) {return a[D]<b[D];}
     
    void update(int k)
    {
        for (int i=0;i<base;++i)
        {
            t[k].mn[i]=min(t[k][i],min(t[t[k].l].mn[i],t[t[k].r].mn[i]));
            t[k].mx[i]=max(t[k][i],max(t[t[k].l].mx[i],t[t[k].r].mx[i]));
        }
    }
     
    int build(int l,int r,int dir)
    {
        D=dir;
        int mid=(l+r)/2;
        nth_element(t+l,t+mid,t+r+1);
        for (int i=0;i<base;++i) t[mid].mn[i]=t[mid].mx[i]=t[mid][i];
        if (l<mid) t[mid].l=build(l,mid-1,(dir+1)%base); else t[mid].l=0;
        if (r>mid) t[mid].r=build(mid+1,r,(dir+1)%base); else t[mid].r=0;
        update(mid);
        return mid;
    }
     
    int dis(node a,node b)
    {
        int ret=0;
        for (int i=0;i<base;++i)
            ret+=(a[i]-b[i])*(a[i]-b[i]);
        return ret;
    }
     
    pair <int,int> pa;
    int ans[maxn];
    priority_queue <pair<int,int> > q;
     
    int getdis(int k)
    {
        if (!k) return inf;
        int ret=0;
        for (int i=0;i<base;++i)
            if (now[i]<t[k].mn[i]) ret+=(t[k].mn[i]-now[i])*(t[k].mn[i]-now[i]);
        for (int i=0;i<base;++i)
            if (now[i]>t[k].mx[i]) ret+=(now[i]-t[k].mx[i])*(now[i]-t[k].mx[i]);
        return ret;
    }
     
    void query(int k)
    {
        if (!k) return ;
        int dl=getdis(t[k].l),dr=getdis(t[k].r),d0=dis(t[k],now);
        if (d0<q.top().first) {q.pop(); q.push(mk(d0,k));}
        if (dl<dr)
        {
            if (dl<q.top().first) query(t[k].l);
            if (dr<q.top().first) query(t[k].r);
        }
        else
        {
            if (dr<q.top().first) query(t[k].r);
            if (dl<q.top().first) query(t[k].l);
        }
    }
     
    int main()
    {
        while (scanf("%d%d",&n,&base)!=EOF)
        {
    //      memset(t,0,sizeof t);
    //      n=read(); base=read();
            for (int i=0;i<base;++i) t[0].mn[i]=inf,t[0].mx[i]=-inf;
            for (int i=1;i<=n;++i) t[i].init();
            rt=build(1,n,0);
            m=read();
            while (m--)
            {
                now.init(); x=read();
                for (int i=0;i<x;++i) q.push(mk(inf,0));
                query(rt);
                printf("the closest %d points are:
    ",x);
                for (int i=x;i>=1;--i) ans[i]=q.top().second,q.pop();
                for (int i=1;i<=x;++i)
                    for (int j=0;j<base;++j)
                        printf("%d%c",t[ans[i]][j],j==base-1?'
    ':' ');
            }
        }
    }
    

      

  • 相关阅读:
    Robot Framework学习笔记V1.0
    新炬网络亿能测试“性能测试和自动化测试”技术研讨会
    js里面关于IE和万恶的IE6的判断
    addLoadEvent(func)有关
    js call和apply[转]
    原生AJAX
    搭建Python开发环境(含Selenium WebDriver安装)
    Python实现随机生成指定数量字符串的函数(方法)记面试问题2
    学习Question持续更新Question和Answer进度20170902
    Python数组和list的区别,tuple和set的区别记面试问题1
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6195029.html
Copyright © 2011-2022 走看看