简单解析几何。
做这道题之前,你需要知道:
-
根据两点求直线一般式。
-
根据两条直线求交点坐标。
这里直接丢公式了,百度上也有证明过程,自己推导难度也不大。
-
若两点坐标为 \((x_1,y_1),(x_2,y_2)\),则直线方程为:\(Ax+By+C=0\),其中 \(A=y_2-y_1,B=x_1-x_2,C=x_2y_1-x_1y_2\)。
-
若两条直线方程为 \(A_1\ x+B_1\ y+C=0,A_2\ x+B_2\ y+C=0\),若 \(A_1B_2=A_2B_1\) 则两直线平行,否则这两条直线有交点为 \(\Large (\frac{C_2B_1-C_1B_2}{A_1B_2-A_2B_1},\frac{C_1A_2-C_2A_1}{A_1B_2-A_2B_1})\)。
那直接暴力把每条直线的交点求出来,判断是否在 \((x_1,y_1),(x_2,y_2)\) 所围成的矩形区域的范围内就可以了,要特判两条直线平行的情况,这里 \((x_1,y_1),(x_2,y_2)\) 指的是学校和家两点的坐标。记得先判断 \(x_1\) 和 \(x_2\),\(y_1\) 和 \(y_2\) 之间的大小关系。
为了避免实数比大小,可以把交点的分母移到不等式另外一边,但是要注意分母正负对不等号方向的影响。
观察到坐标范围能到 \(10^6\),如果两个坐标相乘可能能到达 \(10^{12}\),所以记得开 ll
。
#include<cstdio>
#define ll long long
ll x1,y1,x2,y2;
ll A,B,C;
int n,cnt;
ll a,b,c;
ll fm,x,y;
int main()
{
scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
A=y2-y1,B=x1-x2,C=x2*y1-x1*y2;
if(x2<x1)
{
int t=x2;
x2=x1;
x1=t;
}
if(y2<y1)
{
int t=y2;
y2=y1;
y1=t;
}
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&a,&b,&c);
fm=A*b-a*B,x=c*B-C*b,y=C*a-c*A;
if(fm==0) continue;
if(fm>0&&x1*fm<=x&&x<=x2*fm&&y1*fm<=y&&y<=y2*fm) cnt++;
if(fm<0&&x1*fm>=x&&x>=x2*fm&&y1*fm>=y&&y>=y2*fm) cnt++;
}
printf("%d",cnt);
return 0;
}
标签:直线,x1,题解,ll,CF498A,x2,y1,y2
From: https://www.cnblogs.com/osfly/p/17657988.html