• POJ 2318 TOYS | 二分+判断点在多边形内


    题意:

    给一个矩形的区域(左上角为(x1,y1) 右下角为(x2,y2)),给出n对(u,v)表示(u,y1) 和 (v,y2)构成线段将矩形切割

    这样构成了n+1个多边形,再给出m个点,问每个多边形内有多少个点.

    读入为n,m,x1,y1,x2,y2

    n个数对(u,v),m个数对(x,y) (n,m<=5000)


    题解:

    很暴力的想法是对于每个点,枚举每个多边形进行检查.

    但是多组数据就很江

    考虑一下判断点在多边形内的射线法可知

    枚举一个多边形的时候就可以知道点在多边形的左边还是右边

    这样我们对每个点二分一下他属于那个多边形,依靠上述性质就可以在nlogn时间内做完

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    typedef long long ll;
    #define N 5010
    using namespace std;
    int  n,m,x1,x2,y1,y2,up[N],down[N],cnt[N],t;
    struct point
    {
        int x,y;
        point (){} ;
        point (int _x,int _y) :
    	x(_x),y(_y) {};
        bool operator < (const point &rhs) const
    	{
    	    if (x==rhs.x) return y<rhs.y;
    	    return x<rhs.x;
    	}
        inline int operator * (const point &rhs) const
    	{
    	    return x*rhs.y-y*rhs.x;
    	}
        inline point operator - (const point &rhs) const
    	{
    	    return point(x-rhs.x,y-rhs.y);
    	}
        friend inline int dot (const point &lhs,const point &rhs)
    	{
    	    return lhs.x*rhs.x+lhs.y*rhs.y; 
    	}
    }toy[N];
    bool isinline (const point &p1,const point &p2,const point &p3)
    {
        int det=(p1-p3)*(p2-p3);
        if (det!=0) return 0;
        int Dot=dot(p1-p3,p2-p3);
        return Dot<=0;
    }
    struct polygon
    {
        point p[10];
        int inner (const point &pp)
    	{
    	    int cnt=0;
    	    for (int i=1;i<=4;i++)
    	    {
    		if (isinline(p[i],p[i+1],pp)) return 1;
    		int d1=p[i].y-pp.y,d2=p[i+1].y-pp.y;
    		int del=(p[i]-pp)*(p[i+1]-pp);
    		if ( (del>=0 && d1>=0 && d2<0) ||
    		     (del<=0 && d1<0 && d2>=0) ) cnt++;
    	    }
    	    return cnt;
    	}
    }pol[N];
    void solve()
    {
        sort(toy+1,toy+1+m);
        memset(cnt,0,sizeof(cnt));
        for (int i=0;i<=n;i++)
        {
    	pol[i].p[1]=pol[i].p[5]=point(up[i],y1);
    	pol[i].p[4]=point(down[i],y2);
    	pol[i].p[3]=point(down[i+1],y2);
    	pol[i].p[2]=point(up[i+1],y1);
        }
        for (int i=1;i<=m;i++)
        {
    	int l=0,r=n,mid;
    	while (l<=r)
    	{
    	    mid=l+r>>1;
    	    int res=pol[mid].inner(toy[i]);
    	    if (res&1)
    	    {
    		cnt[mid]++;
    		break;
    	    }
    	    if (res>0) l=mid+1;
    	    else r=mid;
    	}
        }
    }
    int main()
    {
        while (scanf("%d",&n),n)
        {
    	if (++t!=1) puts("");
    	scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
    	for (int i=1;i<=n;i++)
    	    scanf("%d%d",&up[i],&down[i]);
    	for (int i=1,x,y;i<=m;i++)
    	{
    	    scanf("%d%d",&x,&y);
    	    toy[i]=point(x,y);
    	}
    	up[0]=down[0]=x1,up[n+1]=down[n+1]=x2;
    	solve();
    	for (int i=0;i<=n;i++)
    	    printf("%d: %d
    ",i,cnt[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    hdu 5504 GT and sequence
    解决:Incorrect line ending: found carriage return ( ) without corresponding newline ( )
    hdu 5501 The Highest Mark(贪心+01背包)
    web开发学习之路是否有尽头
    2016年后web开发趋势是什么?
    使用 jQuery Mobile 与 HTML5 开发 Web App 系列文章目录
    web开发微信文章目录
    现代web开发需要学习的15大技术
    移动前端重构实战系列
    什么鬼,又不知道怎么命名class了
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8000449.html
Copyright © 2020-2023  润新知