[KD 树]HDU 5992 Finding Hotels

来源:互联网 发布:空性智慧知乎 编辑:程序博客网 时间:2024/05/29 12:15

题意:宾馆和游客的坐标由二维点给出,宾馆有个价格,游客有个能接受的最高价格,输出每个游客能接受的最近宾馆。


宾馆用KD树建树,查询游客时,价格不符合的宾馆不更新答案即可,由于该题时间给的充裕,这种做法也可以过。

#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<vector>#include<set>#include<map>#include<stack>#include<queue>using namespace std;#pragma comment(linker, "/STACK:10240000000,10240000000")#define mem(x,y) memset(x,y,sizeof(x))#define pb push_back#define bug puts("===========");#define REP(i,n) for(int i=0;i<n;i++)#define REP1(i,n) for(int i=1;i<=n;i++)#define ALL(A) A.begin(), A.end()#define T_T for(int _=RD(),test=1;test<=_;test++)typedef long long ll;typedef pair<ll ,ll> pii;#define CHG ch=getchar()#define FRD x=bo=0; for(CHG;ch<'0'||ch>'9';CHG) if(ch=='-')bo=1;#define FR2 for(;ch>='0'&&ch<='9';x=(x<<1)+(x<<3)+ch-'0',CHG);char ch; int bo;inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}inline void RD(int &x){ FRD FR2 if (bo)x=-x; }inline void RD(ll &x){ FRD FR2 if (bo)x=-x; }inline ll RD(){ ll x; RD(x); return x; }inline void RD(char *s){///scanf %s    for (CHG;blank(ch);CHG);    for (;!blank(ch);CHG)*s++=ch; *s=0;}inline void RD(char &c){for(CHG;blank(c);CHG);}template<class T> inline void OT(T x){    static char buf[20];    char *p1=buf;if (!x)*p1++='0';if (x<0)putchar('-'),x=-x;    while(x)*p1++=x%10+'0',x/=10;    while(p1--!=buf)putchar(*p1);}inline void pe(){puts("");}//输出回车inline void pk(){putchar(' ');}//输出空格const double inf=1e7;const ll mod =100000007;const long long INF =2e18+5;#define pii pair<int,int>#define mytype ll /*======================================*/const int NV=1e6;struct point{    mytype x, y;    int c,id;    void in(){        RD(x),RD(y);    }} p[NV];bool Div[NV];int id;bool cmpX(const point &p1,const point &p2){    return p1.x<p2.x;}bool cmpY(const point &p1,const point &p2){    return p1.y<p2.y;}long long dis(const point &p1,const point &p2){    return (long long)(p1.x-p2.x)*(p1.x-p2.x)+(long long)(p1.y-p2.y)*(p1.y-p2.y);}void build(int l, int r, point p[]){    if (l > r) return;    int mid = l + r >> 1;    int minX, minY, maxX, maxY;    minX = min_element(p + l, p + r + 1, cmpX)->x;    minY = min_element(p + l, p + r + 1, cmpY)->y;    maxX = max_element(p + l, p + r + 1, cmpX)->x;    maxY = max_element(p + l, p + r + 1, cmpY)->y;    Div[mid] = (maxX - minX >= maxY - minY);    nth_element(p + l, p + mid, p + r + 1, Div[mid] ? cmpX : cmpY);    build(l, mid - 1, p);    build(mid + 1, r, p);}void find(long long &res, int l, int r, point &a, point p[]){    if (l > r)  return;    int mid = l + r >> 1;    long long dist = dis(a, p[mid]);    if (p[mid].c<=a.c&&(dist<res||(dist==res&&p[mid].id<id))) ///NOTICE      res = dist,id=p[mid].id;    long long d = Div[mid] ? (a.x - p[mid].x) : (a.y - p[mid].y);    int l1, l2, r1, r2;    l1 = l, l2 = mid + 1;    r1 = mid - 1, r2 = r;    if (d > 0) swap(l1, l2), swap(r1, r2);    find(res, l1, r1, a, p);    if (d * d < res) find(res, l2, r2, a, p);}int find(int l,int r, point &a, point p[]){    long long res=INF;    find(res,l,r,a,p);    return id;}point pp[NV];int main(){    T_T{        int n,m;        RD(n),RD(m);        for(int i=1;i<=n;i++)        {            RD(p[i].x),RD(p[i].y);            RD(p[i].c);            p[i].id=i;            pp[i]=p[i];        }        build(1,n,p);        while(m--){            int x,y,c;            RD(x),RD(y),RD(c);            point tmp;            tmp.x=x;tmp.y=y;tmp.c=c;            int k=find(1,n,tmp,p);            printf("%lld %lld %d\n",pp[k].x,pp[k].y,pp[k].c);        }    }    return 0;}



原创粉丝点击