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

  

posted @ 2014-08-23 11:03  阿牧遥  阅读(275)  评论(0编辑  收藏  举报