2018 Beijing online game G topic The Mole

Title:

The two-dimensional plane gives n line segments, one point is asked at a time, and the number of the line segment with the shortest distance to this point is output.

Explanation:
Random data, violence + RP...

The coordinate range is 2 ^ 16. Divide the coordinates into 2 ^ 16 blocks every 2 ^ 8.

When reading in a line segment, add the number of the current line segment to all blocks that the line segment passes through.

Read in a query, find out which block it belongs to, then enumerate the numbers contained in this block, and only find the shortest distance from the point to the line in these line segments.

However, the shortest line segment may not be in this block. Let's check all eight blocks around this block.

Good luck, once through the sample, once on AC.

Code:

#include<bits/stdc++.h>
#define N 257
#define INF 0x3f3f3f3f
#define eps 1e-10
#define pi 3.141592653589793
#define mod 998244353
#define LL long long
#define pb push_back
#define cl clear
#define si size
#define lb lower_bound
#define mem(x) memset(x,0,sizeof x)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define sccc(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
int dcmp(double x){if (fabs(x)<eps)return 0;else return x<0?-1:1;}

struct Point
{
    double x,y;
    bool operator < (const Point &a)const
    {return dcmp(x-a.x)<0 || (dcmp(x-a.x)==0 && dcmp(y-a.y)<0);}
    Point(double x=0,double y=0):x(x),y(y){ }
    void read(){scanf("%lf%lf",&x,&y);}
};
typedef Point Vector;


Vector operator + (Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator * (Vector a,double b){return Vector(a.x*b,a.y*b);}
Vector operator / (Vector a,double b){return Vector(a.x/b,a.y/b);}
bool operator == (Vector a,Vector b){return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;}
double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}  //Dot product
double Length(Vector a){return sqrt(Dot(a,a));}
double Angle(Vector a,Vector b){return acos(min(1.0,max(-1.0,Dot(a,b)/Length(a)/Length(b))));}// Range [0180]
double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;} //Cross product
Point Normal(Point a){ return a/Length(a); }
Vector Rotate(Vector a,double rad)// Vector a rotates rad counterclockwise
{return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));}

struct Seg
{
    Point a,b;
}c[10010];

//The distance from point to line segment, p to line ab. if the distance does not exist, return the distance of the shorter line segment in pa, pb
double DistanceToSegment(Point p,Point a,Point b)
{
    if (a==b)return Length(p-a);
    Vector v1=b-a,v2=p-a,v3=p-b;
    if (dcmp(Dot(v1,v2))<0)return Length(v2);
    else if (dcmp(Dot(v1,v3))>0)return Length(v3);
    else return fabs(Cross(v1,v2))/Length(v1);
}

vector<int> a[N*N];

int f(double x,double y)
{
    int xx=round(x);int yy=round(y);
    return (yy>>8)*(1<<8)+(xx>>8);
}

double ans=1e10;int s;
int t;Point e;
void sdfsd()
{
    for (auto i:a[t])
    {
        double dis=DistanceToSegment(e,c[i].a,c[i].b);
        if (dcmp(dis-ans)<0)
        {
            ans=dis;
            s=i;
        }else
        if (dcmp(dis-ans)==0 && i<s) s=i;
    }
}

int main()
{
    int n,m;
    while(~scc(n,m))
    {
        mem(a);
        for (int i=1;i<=n;i++)
        {
            c[i].a.read();c[i].b.read();
            Vector v=c[i].b-c[i].a;
            v=v/256; int t=-1;
            for (int j=0;j<257;j++)
            {
                Point h=c[i].a+v*j;
                int tt=f(h.x,h.y);
                if (t!=tt) a[tt].pb(i);
                t=tt;
            }
        }
        while(m--)
        {
            ans=1e9;
            e.read();
            int tt=f(e.x,e.y);
            t=tt;              sdfsd();
            t=tt+(1<<8);
            if (t>=0 && t<N*N )sdfsd();
            t++;
            if (t>=0 && t<N*N )sdfsd();
            t-=2;
            if (t>=0 && t<N*N )sdfsd();
            t=tt-(1<<8);
            if (t>=0 && t<N*N )sdfsd();
            t++;
            if (t>=0 && t<N*N )sdfsd();
            t-=2;
            if (t>=0 && t<N*N )sdfsd();
            t=tt+1;
            if (t>=0 && t<N*N )sdfsd();
            t=tt-1;
            if (t>=0 && t<N*N )sdfsd();
            printf("%d\n",s);
        }
    }
}

 

Posted by mikster on Fri, 27 Dec 2019 12:14:33 -0800