POJ 2318 TOYS

来源:互联网 发布:js点击翻牌效果 编辑:程序博客网 时间:2024/04/29 10:26

问每个凸四边形里有几个点,由于上边和下边是给定的,所以只需要判断每个点和每条cardboard partition的左右关系

单调性显然,可以二分来搞,再用叉积判断方向


#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<stack>#include<queue>#include<vector>#include<map>#include<ctime>using namespace std;struct Point{    long long x,y;    void show()    {        cout<<"x="<<x<<" y="<<y<<endl;    }    Point(){};    Point(long long xx,long long yy):x(xx),y(yy){};};struct Vector{    Point a,b;    Vector(){};    Vector(Point x,Point y):a(x),b(y){}    bool operator <(const Vector &t)const    {        int x1=min(t.a.x,t.b.x);        int x2=min(a.x,b.x);        return x2<x1;    }}line[5005];int cnt[5005],res[5005],n,m;bool mul(Point a,Point b,Point c){   // a.show(); b.show(); c.show();    int res=(a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);    return res>=0;//ca在cb的顺时针方向}int get(Point p){    int l=-1,r=n+1,mid;    while(l+1<r)    {        mid=(l+r)>>1;       // printf("%d %d %d %d\n",l,mid,r,mul(line[mid].a,line[mid].b,p));        if(mul(line[mid].a,line[mid].b,p))            l=mid;        else            r=mid;    }    return l;}int main(){    int i,j,k;    long long x1,y1,x2,y2,u,d,x,y;    while(scanf("%d",&n)!=EOF&&n)    {        memset(cnt,0,sizeof(cnt));        scanf("%d%lld%lld%lld%lld",&m,&x1,&y1,&x2,&y2);        line[0]=Vector(Point(x1,y1),Point(x1,y2));        for(i=1;i<=n;i++)        {            scanf("%lld%lld",&u,&d);            line[i]=Vector(Point(u,y1),Point(d,y2));        }        sort(line,line+n+1);        while(m--)        {            scanf("%lld%lld",&x,&y);            j=get(Point(x,y));            //cout<<"j="<<j<<endl;            cnt[j]++;        }        puts("Box");        memset(res,0,sizeof(res));        for(i=0;i<=n;i++)            res[cnt[i]]++;        for(i=1;i<=n;i++)            if(res[i]!=0)                printf("%d: %d\n",i,res[i]);    }    return 0;}


原创粉丝点击