hdu 1086 线段相交
這個題目就是基本的線段相交水題。
并且重復點竟然算2個,哪沒辦法了,水過,線段相交,跨立實驗。
如何判斷兩條線段是否相交
判斷兩條線段是否相交?
(1) 快速排斥試驗
設以線段 P1P2 為對角線的矩形為 R , 設以線段 Q1Q2 為對角線的矩形為 T ,如果 R 和 T?
不相交,顯然兩線段不會相交。
(2) 跨立試驗
如果兩線段相交,則兩線段必然相互跨立對方。若 P1P2 跨立 Q1Q2 ,則矢量 ( P1 - Q1 ) 和
? ? ? ( P2 - Q1 ) 位于矢量 ( Q2 - Q1 ) 的兩側,
? ? ? 即 ( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) < 0 。
? ? ? ?上式可改寫成 ( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) > 0 。
? ? ? 當 ( P1 - Q1 ) × ( Q2 - Q1 ) = 0 時,說明 ( P1 - Q1 ) 和 ( Q2 - Q1 ) 共線,
? ? ? 但是因為已經通過快速排斥試驗,所以 P1 一定在線段 Q1Q2 上;
? ? ? 同理, ( Q2 - Q1 ) ×(P2 - Q1 ) = 0 說明 P2 一定在線段 Q1Q2 上。
? ? ?所以判斷 P1P2 跨立 Q1Q2 的依據是:?
? ? ? ( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0 。
? ? ? 同理判斷 Q1Q2 跨立 P1P2 的依據是:
? ? ? ( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0 。
代碼如下:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const double eps=1e-10; const int maxn=500; struct point{double x,y; }; point p[maxn],b[maxn]; bool ans[maxn]; double min(double a,double b) {return a < b ? a : b; } double max(double a,double b) {return a > b ? a : b; } bool inter(point a, point b, point c, point d){if( min(a.x, b.x) > max(c.x, d.x) ||min(a.y, b.y) > max(c.y, d.y) ||min(c.x, d.x) > max(a.x, b.x) ||min(c.y, d.y) > max(a.y, b.y) )return 0;double h, i, j, k;h = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);//叉積i = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x);j = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x);k = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x);return h * i <= eps && j * k <= eps; } int main() {int n;while(scanf("%d",&n),n){int i,j;for(i=0;i<n;i++){scanf("%lf %lf",&p[i].x,&p[i].y);scanf("%lf %lf",&b[i].x,&b[i].y);}int ans=0;for(i=0;i<n;i++)for(j=i+1;j<n;j++){if(inter(p[i],b[i],p[j],b[j])) ans++;}printf("%d\n",ans);}return 0; }總結
以上是生活随笔為你收集整理的hdu 1086 线段相交的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 2036 计算多边形面积
- 下一篇: hdu 1392 Surround th