那些年不想写的计算几何,总有一天要还。
直接枚举点,枚举四边形即可,只要用叉乘判断点是否在两条线段中间即可。
O ( n m ) O(nm) O(nm)
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 5010
#define eps 1e-8
inline int sgn(double x){return x<-eps?-1:x>eps;}
inline double my_sqrt(double x){if(x<eps) return 0;return sqrt(x);}
inline double sqr(double x){return x*x;}
struct point{
double x,y;
point(double x=0,double y=0):x(x),y(y){}
inline double norm()const{return my_sqrt(x*x+y*y);}
inline double norm2() const {return x*x+y*y;}
inline point unit() const {double len=norm();return point(x/len,y/len);}
inline point negate()const{return point(-x,-y);}
inline point rot90() const {return point(-y,x);}//counter_clockwise
inline point _rot90() const {return point(y,-x);}//clockwise
inline point rotate(double theta) const {//counter_clockwise
double c=cos(theta),s=sin(theta);
return point(x*c-y*s,x*s+y*c);
}
int get(){return scanf("%lf%lf",&x,&y);}
void out(){printf("(%.6lf,%.6lf)\n",x,y);}
};
inline bool operator==(const point &a,const point &b){
return fabs(a.x-b.x)<=eps&&fabs(a.y-b.y)<=eps;
}
inline bool operator!=(const point &a,const point &b){
return fabs(a.x-b.x)>eps||fabs(a.y-b.y)>eps;
}inline bool operator<(const point &a,const point &b){
if(fabs(a.x-b.x)>eps) return a.x<b.x;
return a.y+eps<b.y;
}
inline point operator+(const point &a,const point &b){
return point(a.x+b.x,a.y+b.y);
}
inline point operator-(const point &a,const point &b){
return point(a.x-b.x,a.y-b.y);
}
inline point operator*(const point &a,const double &b){
return point(a.x*b,a.y*b);
}
inline point operator/(const point &a,const double &b){
return point(a.x/b,a.y/b);
}
inline double det(const point &a,const point &b){
return a.x*b.y-b.x*a.y;
}
inline double dot(const point &a,const point &b){
return a.x*b.x+a.y*b.y;
}
inline double dis(const point &a,const point &b){
return my_sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
struct line{
point s,t;
line(point s=point(),point t=point()):s(s),t(t){}
inline double length() const {return dis(s,t);}
}li[N];
//线段交点
//注意如果两条线段是共线的且有交点,那么intersect_judgement确实会返回true
//但是line_intersect会求错,所以这种情况需要特判
inline bool point_on_segment(const point &a,const line &b){
return sgn(det(a-b.s,b.t-b.s))==0&&dot(b.s-a,b.t-a)<eps;
}
inline bool two_side(const point &a,const point &b,const line &c){
return sgn(det(a-c.s,c.t-c.s))*sgn(det(b-c.s,c.t-c.s))<0;
}
inline bool intersect_judgement(const line &a,const line &b){
if(point_on_segment(b.s,a)||point_on_segment(b.t,a)) return 1;
if(point_on_segment(a.s,b)||point_on_segment(a.t,b)) return 1;
return two_side(a.s,a.t,b)&&two_side(b.s,b.t,a);
}
inline point line_intersect(const line &a,const line &b){
double s1=det(a.t-a.s,b.s-a.s);
double s2=det(a.t-a.s,b.t-a.s);
return (b.s*s2-b.t*s1)/(s2-s1);
}
inline double point_to_line(const point &a,const line &b){
return fabs(det(b.t-b.s,a-b.s))/dis(b.s,b.t);
}
point project_to_line(const point &a,const line &b){
return b.s+(b.t-b.s)*(dot(a-b.s,b.t-b.s)/(b.t-b.s).norm2());
}
inline double point_to_segment(const point &a,const line &b){
if(sgn(dot(b.s-a,b.t-b.s))*sgn(dot(b.t-a,b.t-b.s))<=0) return fabs(det(b.t-b.s,a-b.s))/dis(b.s,b.t);
return min(dis(a,b.s),dis(a,b.t));
}
bool in_polygon(const point &p,const vector<point> &poly){
int n=(int)poly.size();
int counter=0;
for(int i=0;i<n;++i){
point a=poly[i],b=poly[(i+1)%n];
if(point_on_segment(p,line(a,b))) return 0;//bounded excluded
int x=sgn(det(p-a,b-a));
int y=sgn(a.y-p.y);
int z=sgn(b.y-p.y);
if(x>0&&y<=0&&z>0) counter++;
if(x<0&&z<=0&&y>0) counter--;
}
return counter!=0;
}
struct circle{
point center;
double radius;
circle(point center=point(),double radius=0) : center(center),radius(radius) {}
};
inline bool operator==(const circle &a,const circle &b){
return a.center==b.center&&fabs(a.radius-b.radius)<eps;
}
inline bool operator!=(const circle &a,const circle &b){
return a.center!=b.center||fabs(a.radius-b.radius)>eps;
}
inline bool in_circle(const point &p,const circle &c){
return dis(p,c.center)<c.radius+eps;
}
point circumcenter(const point &a,const point &b,const point &c){//三角形的外心
point p=b-a,q=c-a,s(dot(p,p)/2,dot(q,q)/2);
double d=det(p,q);
return a+point(det(s,point(p.y,q.y)),det(point(p.x,q.x),s))/d;
}
//圆的生成函数
circle make_circle(const point &a,const point &b){
return circle((a+b)/2,dis(a,b)/2);
}
circle make_circle(const point &a,const point &b,const point &c){
point center=circumcenter(a,b,c);
return circle(center,dis(center,a));
}
//直线与圆的交点
//返回ab方向的第一个交点
point line_circle_intersect(const line &l,const circle &c){
double x=my_sqrt(sqr(c.radius)-sqr(point_to_line(c.center,l)));
return project_to_line(c.center,l)+(l.s-l.t).unit()*x;
}
//圆与圆的交点
point circle_intersect(const circle &a,const circle &b){//get another point using circle_intersect(b,a)
point r=(b.center-a.center).unit();
double d=dis(a.center,b.center);
double x=.5*((sqr(a.radius)-sqr(b.radius))/d+d);
double h=my_sqrt(sqr(a.radius)-sqr(x));
return a.center+r*x+r.rot90()*h;
}
//点到圆的切线
pair<line,line> tangent(const point &p,const circle &c){
circle a=make_circle(p,c.center);
return make_pair(circle_intersect(a,c),circle_intersect(c,a));
}
int n,m,ans[N];
inline bool check(const point &p,const line &a,const line &b){
return sgn(det(p-a.s,a.t-a.s))*sgn(det(p-b.s,b.t-b.s))<=0;
}
int main(){
// freopen("a.in","r",stdin);
while(1){
scanf("%d",&n);
if(!n) break;
int x1,y1,x2,y2;
memset(ans,0,sizeof(ans));
scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
li[0]=line(point(x1,y2),point(x1,y1));
li[n+1]=line(point(x2,y2),point(x2,y1));
for(int i=1;i<=n;++i){
int x3,x4;scanf("%d%d",&x3,&x4);
li[i]=line(point(x4,y2),point(x3,y1));
}
while(m--){
int x,y;scanf("%d%d",&x,&y);
if(x==x1){ans[0]++;continue;}
if(x==x2){ans[n]++;continue;}
for(int i=0;i<=n;++i){
if(check(point(x,y),li[i],li[i+1])){
ans[i]++;break;
}
}
}
for(int i=0;i<=n;++i) printf("%d: %d\n",i,ans[i]);
puts("");
}
return 0;
}