1264 線段相交解題報告(51nod)
阿新 • • 發佈:2018-12-14
給出平面上兩條線段的兩個端點,判斷這兩條線段是否相交(有一個公共點或有部分重合認為相交)。 如果相交,輸出"Yes",否則輸出"No"。
Input
第1行:一個數T,表示輸入的測試數量(1 <= T <= 1000) 第2 - T + 1行:每行8個數,x1,y1,x2,y2,x3,y3,x4,y4。(-10^8 <= xi, yi <= 10^8) (直線1的兩個端點為x1,y1 | x2, y2,直線2的兩個端點為x3,y3 | x4, y4)
Output
輸出共T行,如果相交輸出"Yes",否則輸出"No"。
Input示例
2 1 2 2 1 0 0 2 2 -1 1 1 1 0 0 1 -1
Output示例
Yes No
我開始時這樣想的
在圖中,若兩線段相交,這四個向量(a1,a2,a3,a4)會有一定的關係 ,即若相交,則(a1+a2)*(a3+a4)<0-------------結果這種方法不行
其實發現只要四個端點形成的四邊形是凸四邊形(這個該怎麼判斷呢,),則兩線段相交。
別人是用叉積算的:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; struct Point { double x; double y; }; Point a,b,c,d; //叉積 double mult(Point a, Point b, Point c) { return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y); } //aa, bb為一條線段兩端點 cc, dd為另一條線段的兩端點 相交返回true, 不相交返回false bool intersect(Point aa, Point bb, Point cc, Point dd) { if ( max(aa.x, bb.x)<min(cc.x, dd.x) ) { return false; } if ( max(aa.y, bb.y)<min(cc.y, dd.y) ) { return false; } if ( max(cc.x, dd.x)<min(aa.x, bb.x) ) { return false; } if ( max(cc.y, dd.y)<min(aa.y, bb.y) ) { return false; } if ( mult(cc, bb, aa)*mult(bb, dd, aa)<0 ) { return false; } if ( mult(aa, dd, cc)*mult(dd, bb, cc)<0 ) { return false; } return true; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y); if(intersect(a,b,c,d)) printf("Yes\n"); else printf("No\n"); } return 0; }