J-single dog salvation (lower convex hull) 2019 program design competition of South China University of Technology (spring competition)

Title Link: Doraemon portal

Meaning: girls have a beauty level of B1, intelligence level of I1, boys have a handsome level of B2, intelligence level of I2.

Now there are n boys and m girls. You need to find the most suitable boy for m girls. One boy can be selected by multiple girls.

The suitability of girls and boys is:

      

To simplify:It can be seen that it is actually the direct slope between the girl point and the boy point.

 

We first arrange all the points in order (first by x, then by y), and then we make a lower convex hull for these boy points. When we meet a girl point, we construct a lower convex hull just before the girl point to divide a boy point with the largest slope. Why do we need to lower the convex hull instead of the upper convex hull? Because when we meet a girl point, we always find a point on the left, making the slope the most Big, then he should try his best to look down.

What we are looking for above is a boy's point for each girl on the left side of the point, but it's possible that the best boy's point for this girl is not on the left side, but on the right side, so we need to lower the convex hull again, this time from the back.

 

Figure 1: see code Figure 2: see code

                                           

 

The code program refers to the official program.

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int maxn=200010;

struct point{

    LL x,y;///Coordinates of points
    int id,flag; ///id indicates the position of this point, flag=1 indicates that this point is a boy point, and flag=2 indicates a girl point
    point(){}
    point(LL _x,LL _y,int _id,int _flag){
        x=_x;y=_y;id=_id;flag=_flag;
    }

    bool operator < (const point &b){
    return x==b.x?y<b.y:x<b.x;
    }
}p[maxn],ch[maxn],ans1[maxn],ans2[maxn];

int pos[maxn],tot;

point operator + (point a,point b){ return point(a.x+b.x,a.y+b.y,0,0);}
point operator - (point a,point b) {  return point(a.x-b.x,a.y-b.y,0,0);}




LL cross(point a,point b){  return a.x*b.y-a.y*b.x;}

///Ex boyfriend, girl, present boyfriend
bool judge(point a,point b,point c){
    LL item=cross(a-b,c-b);

    ///For both, choose the youngest boyfriend
    return item==0?c.id<a.id:item<0;
}

void andrew(int n)
{
    tot=-1;

    for(int i=0;i<n;i++)
    {
        ///When you meet a boy
        if(p[i].flag==1){
        while(tot>0&&cross(ch[tot]-ch[tot-1],p[i]-ch[tot-1])<0)
            tot--;
        ch[++tot]=p[i];
        }
        else{

            if(tot==-1) continue;
            int l=0,r=tot;
            ///Finding the optimal point of convex hull under dichotomy
            while(l<r)
            {
                int mid=(l+r)>>1;
                    /// see Figure 1
                if(cross(ch[mid+1]-ch[mid],p[i]-ch[mid])>0)
                    l=mid+1;
                else r=mid;
            }
                ///If the girl hasn't been matched, give her the boy directly. To match, compare the two boys
            if(pos[p[i].id]==-1||judge(ans1[pos[p[i].id]],ans2[p[i].id],ans1[ch[l].id]))
                pos[p[i].id]=ch[l].id;
        }
    }
}

int main()
{

    int n,m;
    LL x1,y1;
    scanf("%d%d",&n,&m);

    for(int i=0;i<n+m;i++)
    {
        scanf("%lld%lld",&x1,&y1);
        if(i<n){
                ///ans1 stores boys' points
            ans1[i]=point(x1,y1,i,1);
            p[i]=ans1[i];///p store all points
        }
        else{
            ///ans2 stores girls' points
            ans2[i-n]=point(x1,y1,i-n,2);
            p[i]=ans2[i-n];
        }
    }

    memset(pos,-1,sizeof(pos));
    ///Sort all points
    sort(p,p+n+m);

    ///For the first time, lower the convex hull and find the best boy point on the left side of the girl point
    andrew(n+m);


    ///For the second time, find the best boy point on the right side of the girl point
    ///Flip and reverse all coordinates
    reverse(p,p+n+m);
    for(int i=0;i<n+m;i++)
    {
        p[i].x=-p[i].x;
        p[i].y=-p[i].y;
    }
    andrew(n+m);

    for(int i=0;i<m;i++)
        printf("%d\n",pos[i]+1);


    return 0;
}

 

My tag: be a passionate programmer.

Posted by Teh Unseen on Tue, 26 Nov 2019 13:31:04 -0800