*[hackerrank]Jim Beam
https://www.hackerrank.com/contests/infinitum-aug14/challenges/jim-beam
学习了线段相交的判断法。首先是叉乘,叉乘的几何意义是有向的平行四边形的面积(除以2就是三角形的面积)。如果ABD和ABC正负相反,说明C和D在AB两侧,同样的,再判断A和B是否在CD两侧即可。当某三角形面积为0时,需要判断是否在线段上。
#include <iostream> using namespace std; typedef long long LL; LL cross_product(LL ax, LL ay, LL bx, LL by, LL cx, LL cy) { return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax); } bool inside(LL ax, LL ay, LL bx, LL by, LL cx, LL cy) { return (min(ax, bx) <= cx && cx <= max(ax, bx) && min(ay, by) <= cy && cy <= max(ay, by)); } bool intersect(LL ax, LL ay, LL bx, LL by, LL cx, LL cy) { LL abc = cross_product(ax, ay, bx, by, cx, cy); LL abd = cross_product(ax, ay, bx, by, 0, 0); LL cda = cross_product(cx, cy, 0, 0, ax, ay); LL cdb = cross_product(cx, cy, 0, 0, bx, by); if (((abc > 0 && abd < 0) || (abc < 0 && abd > 0)) && ((cda > 0 && cdb < 0) || (cda < 0 && cdb > 0))) return true; if (abc == 0 && inside(ax, ay, bx, by, cx, cy)) return true; if (abd == 0 && inside(ax, ay, bx, by, 0, 0)) return true; if (cda == 0 && inside(cx, cy, 0, 0, ax, ay)) return true; if (cdb == 0 && inside(cx, cy, 0, 0, bx, by)) return true; return false; } void solve() { int x1, y1, x2, y2, x, y; cin >> x1 >> y1 >> x2 >> y2 >> x >> y; if (intersect(x1, y1, x2, y2, x, y)) cout << "NO" << endl; else cout << "YES" << endl; } int main() { int t; cin >> t; while (t--) { solve(); } return 0; }