标签:问题 col mat efi opera fine ++ i++ register
题目描述:
给定 $n$ 条线段,求相交的线段对数
(计算几何初步学习题~)
对于向(矢)量 $a , b$ 的叉乘,结果是一个标量,绝对值为 $a,b$ 所成平行四边形的面积 $S$ 。
若 $a$ X $b>0$ , 则可知 $b$ 在 $a$ 逆时针方向,反之亦同,而值为 $0$ 则共线(可以反向)。 (我也不知道为什么,还没学那么深就先记下结论8)
以此可以判断两条线段共线问题: 将线段转为向量,若线段 $AB$ 插在 $CD$ 内,则一定有 $AC$ 与 $AD$ 分别在 $AB$ 的不同反向,即相乘的值小于等于 $0$。
对于 $CD$ 的情况亦同。
注意可能有精度上的问题,需要设置一个 $EPS$
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #define R register 5 const double EPS = 1e-9; 6 using namespace std; 7 int n; 8 struct Node{ 9 double x,y; 10 }S[105],T[105]; 11 inline Node operator -(Node u, Node v)//点坐标相减得到向量 12 { 13 return (Node){u.x - v.x, u.y - v.y}; 14 } 15 inline double operator *(Node u,Node v)//向量×乘 16 { 17 return u.x * v.y - u.y * v.x; 18 } 19 int main() 20 { 21 int Ans = 0; 22 scanf("%d",&n); 23 for(R int i = 1; i <= n; i++) 24 scanf("%lf%lf%lf%lf",&S[i].x,&S[i].y,&T[i].x,&T[i].y); 25 for(R int i = 1; i < n; i++) 26 for(R int j = i + 1; j <= n; j++) 27 { 28 if(((T[i] - S[i]) * (S[j] - S[i])) * ((T[i] - S[i]) * (T[j] - S[i])) <= EPS && ((T[j] - S[j]) * (S[i] - S[j])) * ((T[j] - S[j]) * (T[i] - S[j])) <= EPS) 29 ++Ans; 30 } 31 printf("%d",Ans); 32 return 0; 33 }
标签:问题 col mat efi opera fine ++ i++ register
原文地址:https://www.cnblogs.com/QuickSilverX/p/10988944.html