#include<stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <iostream>
#define max 5000
using namespace std;
const double eps = 1e-8;
struct point{double x,y;};
struct line {point a,b;};
line L[max];
point base;
int T,N;
bool dy(double x,double y) { return x > y + eps;} // x > y
bool xy(double x,double y) { return x < y - eps;} // x < y
bool dyd(double x,double y) { return x > y - eps;} // x >= y
bool xyd(double x,double y) { return x < y + eps;} // x <= y
bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y
double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向
{
return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y);
}
double dis(point p1,point p2)
{
return((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
point intersection(line l1,line l2)
{
point ans = l1.a;
double t = ((l1.a.x - l2.a.x)*(l2.a.y - l2.b.y) - (l1.a.y - l2.a.y)*(l2.a.x - l2.b.x))/
((l1.a.x - l1.b.x)*(l2.a.y - l2.b.y) - (l1.a.y - l1.b.y)*(l2.a.x - l2.b.x));
ans.x += (l1.b.x - l1.a.x)*t;
ans.y += (l1.b.y - l1.a.y)*t;
return ans;
}
double dot(point a,point b,point c)
{
return (c.x-a.x)*(b.x-a.x)+(c.y-a.y)*(b.y-a.y);
}
bool judge(point p,line l)
{
line tmp;
point ans;
tmp.a=base,tmp.b=p;
if(dd(crossProduct(base,p,l.a),0)&&dd(crossProduct(base,p,l.b),0))
return (dyd(dot(base,p,l.a),0)||dyd(dot(base,p,l.b),0));
if(xyd(crossProduct(base,p,l.a)*crossProduct(base,p,l.b),0))
{
ans=intersection(tmp,l);
return dyd(dot(base,p,ans),0);
}
else return false;
}
int main()
{
scanf("%d",&T);
while(T--)
{
int num=0;
scanf("%d",&N);
for (int i=0;i<N;i++)
scanf("%lf%lf%lf%lf",&L[i].a.x,&L[i].a.y,&L[i].b.x,&L[i].b.y);
scanf("%lf%lf",&base.x,&base.y);
for (int i=0;i<N;i++)
{
int tmp1,tmp2;
tmp1=tmp2=0;
for (int j=0;j<N;j++)
{
tmp1+=(judge(L[i].a,L[j]));
tmp2+=(judge(L[i].b,L[j]));
}
if(tmp1>num)
num=tmp1;
if(tmp2>num)
num=tmp2;
}
printf("%d\n",num);
}
return 0;
}
枚举每个端点和原点组成的射线与其他线段是否相交,若相交还需判断交点是否在射线上,用点积判断
开始怕超时用极角排序,但更麻烦,每个极角对应一个极角范围,逆时针旋转扫描,用正负符号表示线段的开始和结束极角,但是会出现极角范围大于180度的情况需要特殊处理,实在太麻烦不好搞