51-nod 1264 線段相交
阿新 • • 發佈:2018-12-13
基準時間限制:1 秒 空間限制:131072 KB 分值: 0 難度:基礎題
給出平面上兩條線段的兩個端點,判斷這兩條線段是否相交(有一個公共點或有部分重合認為相交)。 如果相交,輸出"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
李陶冶 (題目提供者)
題解:這道題就是用差積來判斷線段 是否相交
比如線段AB CD
ABxBC>0表示C在AB的順時針方向ABxBD>0說明D也在順時針方向 這兩個差積同號表示C D線上段AB 同側
在判斷A B在CD哪側就可以判斷是否相交
簡而言之 可以先想想直線與線段相交的條件
另 也可以先用快速排斥再判斷至少一次跨立判斷就也OK
每天進步一點點
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> using namespace std; const double p=1e-10; struct node { double x,y; }a,b,c,d; int jisuan(node a,node b,node c,node d) { double p1,p2,p3,p4; p1=(d.x-c.x)*(d.y-a.y)-(d.y-c.y)*(d.x-a.x);//DCxDA p2=(d.x-c.x)*(d.y-b.y)-(d.y-c.y)*(d.x-b.x);//DCxDB p3=(b.x-a.x)*(b.y-d.y)-(b.y-a.y)*(b.x-d.x);//BAxBD p4=(b.x-a.x)*(b.y-c.y)-(b.y-a.y)*(b.x-c.x);//BAxBC if(p1*p2<=p&&p3*p4<=p)//double判斷有精度問題 注意 return 1; return 0; } void duandian() { scanf("%lf%lf",&a.x,&a.y); scanf("%lf%lf",&b.x,&b.y); scanf("%lf%lf",&c.x,&c.y); scanf("%lf%lf",&d.x,&d.y); if(jisuan(a,b,c,d)) cout<<"yes"<<endl; else cout<<"no"<<endl; } int main() { int T; cin>>T; while(T--) { duandian(); } return 0; }