*[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;

}

  

你可能感兴趣的:(rank)