zoukankan      html  css  js  c++  java
  • HDU 5992/nowcoder 207K

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5992

    题目链接:https://www.nowcoder.com/acm/contest/207/K

    Problem Description
    There are N hotels all over the world. Each hotel has a location and a price. M guests want to find a hotel with an acceptable price and a minimum distance from their locations. The distances are measured in Euclidean metric.

    Input
    The first line is the number of test cases. For each test case, the first line contains two integers N (N ≤ 200000) and M (M ≤ 20000). Each of the following N lines describes a hotel with 3 integers x (1 ≤ x ≤ N), y (1 ≤ y ≤ N) and c (1 ≤ c ≤ N), in which x and y are the coordinates of the hotel, c is its price. It is guaranteed that each of the N hotels has distinct x, distinct y, and distinct c. Then each of the following M lines describes the query of a guest with 3 integers x (1 ≤ x ≤ N), y (1 ≤ y ≤ N) and c (1 ≤ c ≤ N), in which x and y are the coordinates of the guest, c is the maximum acceptable price of the guest.

    Output
    For each guests query, output the hotel that the price is acceptable and is nearest to the guests location. If there are multiple hotels with acceptable prices and minimum distances, output the first one.

    Sample Input
    2
    3 3
    1 1 1
    3 2 3
    2 3 2
    2 2 1
    2 2 2
    2 2 3
    5 5
    1 4 4
    2 1 2
    4 5 3
    5 2 1
    3 3 5
    3 3 1
    3 3 2
    3 3 3
    3 3 4
    3 3 5

    Sample Output
    1 1 1
    2 3 2
    3 2 3
    5 2 1
    2 1 2
    2 1 2
    1 4 4
    3 3 5

    题意:

    给出 $N$ 个酒店,每个酒店有坐标 $(x,y)$,价格为 $c$;同时又给出 $M$ 个人,同样每个人都有坐标 $(x,y)$,每个人能接收的最高酒店价格为 $c$;

    每个人会选择不高于自己可接受价格的酒店中最近的那一个,如果同时有多个酒店同样最近,选择编号的那一个。

    题解:

    根据题目里的费用要求同距离输出编号最小酒店两个要求,对KDTree模板进行一点小修改即可。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
     
    const int maxn=2e5+10;
    const int maxdim=2;
     
    namespace KDTree
    {
        int K;//维数
        inline double sqr(double x){return x*x;}
        struct Point
        {
            int x[maxdim];
            int c;
            int idx;
            double distance(const Point &oth)const
            {
                double ret=0;
                for(int i=0;i<K;i++) ret+=sqr(x[i]-oth.x[i]);
                return ret;
            }
            void input(int _idx)
            {
                idx=_idx;
                for(int i=0;i<K;i++) scanf("%d",&x[i]);
                scanf("%d",&c);
            }
            void output()
            {
                for(int i=0;i<K;i++) printf("%d ",x[i]);
                printf("%d
    ",c);
            }
        };
        struct cmpx
        {
            int div;
            cmpx(const int &_div){div=_div;}
            bool operator()(const Point &a,const Point &b)
            {
                for(int i=0;i<K;i++)
                {
                    int k=(div+i)%K;
                    if(a.x[k]!=b.x[k]) return a.x[k]<b.x[k];
                }
                return true;
            }
        };
        inline bool cmp(const Point &a,const Point &b,int div)
        {
            cmpx cp=cmpx(div);
            return cp(a,b);
        }
     
        struct Node //KDTree的节点
        {
            Point e;
            Node *lc,*rc;
            int div;
        }pool[maxn],*tail,*root;
        void init(){tail=pool;} //初始化KDTree
        Node* Build(Point *a,int l,int r,int div) //建树
        {
            if(l>=r) return NULL;
            Node *p=tail++;
            p->div=div;
            int mid=(l+r)/2;
            nth_element(a+l,a+mid,a+r,cmpx(div));
            p->e=a[mid];
            p->lc=Build(a,l,mid,(div+1)%K);
            p->rc=Build(a,mid+1,r,(div+1)%K);
            return p;
        }
     
        struct Qnode
        {
            Point p;
            double dist;
            Qnode(){}
            Qnode(Point _p,double _dist){p=_p; dist=_dist;}
            bool operator <(const Qnode &oth)const{return dist<oth.dist;}
        };
        priority_queue<Qnode> Q;
        void Search(const Point &p,Node *now,int div,int m) //在now节点子树下搜索p点的m近邻
        {
            if(now==NULL) return;
            if(cmp(p,now->e,div))
            {
                Search(p,now->lc,(div+1)%K,m);
                if(Q.size()<m)
                {
                    if(now->e.c <= p.c) Q.push(Qnode(now->e,p.distance(now->e)));
                    Search(p,now->rc,(div+1)%K,m);
                }
                else
                {
                    if(p.distance(now->e) < Q.top().dist || (p.distance(now->e) == Q.top().dist && now->e.idx < Q.top().p.idx))
                    {
                        if(now->e.c <= p.c)
                        {
                            Q.pop();
                            Q.push(Qnode(now->e,p.distance(now->e)));
                        }
                    }
                    if(sqr((now->e.x[div])-(p.x[div])) < Q.top().dist) Search(p,now->rc,(div+1)%K,m);
                }
            }
            else
            {
                Search(p,now->rc,(div+1)%K,m);
                if(Q.size()<m)
                {
                    if(now->e.c <= p.c) Q.push(Qnode(now->e,p.distance(now->e)));
                    Search(p,now->lc,(div+1)%K,m);
                }
                else
                {
                    if(p.distance(now->e) < Q.top().dist || (p.distance(now->e) == Q.top().dist && now->e.idx < Q.top().p.idx))
                    {
                        if(now->e.c <= p.c)
                        {
                            Q.pop();
                            Q.push(Qnode(now->e,p.distance(now->e)));
                        }
                    }
                    if(sqr((now->e.x[div])-(p.x[div])) < Q.top().dist) Search(p,now->lc,(div+1)%K,m);
                }
            }
        }
     
        void Search(const Point &p,int m) //搜索p点的m近邻
        {
            while(!Q.empty()) Q.pop();
            Search(p,root,0,m);
        }
    };
     
    int n,m;
    KDTree::Point p[maxn];
     
    int main()
    {
        KDTree::K=2;
        int T;
        cin>>T;
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++) p[i].input(i);
            KDTree::init();
            KDTree::root=KDTree::Build(p,0,n,0);
     
            KDTree::Point o;
            for(int i=1;i<=m;i++)
            {
                o.input(i);
                KDTree::Search(o,1);
                o=KDTree::Q.top().p;
                o.output();
            }
        }
    }

    PS.由于只需要最近邻,所以其实并不需要那个优先队列,只不过懒得改了。

  • 相关阅读:
    我不想安于当前的限度,以达到所谓的幸福,回顾下2020年的我
    CentOS 7 搭建 TinyProxy 代理 &&python 脚本访问
    使用国内源来安装pytorch速度很快
    opencv-python的格式转换 RGB与BGR互转
    自签SSL证书以及https的双向认证 实现nginx双向代理
    springboot使用 @EnableScheduling、@Scheduled开启定时任务
    微信下载对账单
    SpringBoot 中定时执行注解(@Scheduled、@EnableScheduling)
    使用idea合并 dev分支合并到test分支
    .Net Core + Entity Framework 调用Oracle 存储过程
  • 原文地址:https://www.cnblogs.com/dilthey/p/9763541.html
Copyright © 2011-2022 走看看