• FOJ Problem 2273 Triangles


    Problem 2273 Triangles

    Accept: 201    Submit: 661
    Time Limit: 1000 mSec    Memory Limit : 262144 KB

    Problem Description

    This is a simple problem. Given two triangles A and B, you should determine they are intersect, contain or disjoint. (Public edge or point are treated as intersect.)

    Input

    First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.

    For each test case: X1 Y1 X2 Y2 X3 Y3 X4 Y4 X5 Y5 X6 Y6. All the coordinate are integer. (X1,Y1) , (X2,Y2), (X3,Y3) forms triangles A ; (X4,Y4) , (X5,Y5), (X6,Y6) forms triangles B.

    -10000<=All the coordinate <=10000

    Output

    For each test case, output “intersect”, “contain” or “disjoint”.

    Sample Input

    2 0 0 0 1 1 0 10 10 9 9 9 10 0 0 1 1 1 0 0 0 1 1 0 1

    Sample Output

    disjoint intersect

    Source

    第八届福建省大学生程序设计竞赛-重现赛(感谢承办方厦门理工学院)  
     
    思路:先判断其中一个三角形a的顶点是否都在另一个三角形b的内部,或者有点在另一个三角形b的边上,抑或b的外部和内部都有a的顶点,这三种情况都好判断,直接输出判断结果。若a的三个顶点都在b的外部,继续判断b的三个顶点与a的关系,可能的关系:b的三个顶点都在a的外部,b的顶点在a内部外部都有,b的顶点都在a的内部。后两种情况好判断,输出结果。第一种情况则要继续判断,此时a,b的顶点都在对方三角形的外部,此时有可能相交,也有可能相离,只需要判断一下其中一个三角形的一条边是否和另一个三角形的某条边相交即可。
    AC代码:
    #define _CRT_SECURE_NO_DEPRECATE
    #include <iostream>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<bitset>
    #include<set>
    #include<map>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define N_MAX 10000+4
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define EPS 1e-8
    typedef long long ll;
    struct point {
        double x, y;
        point(double x = 0, double y = 0) :x(x), y(y) {}
        point operator + (point p) { return point(x + p.x, y + p.y); }
        point operator - (point p) { return point(x - p.x, y - p.y); }
        point operator * (double a) { return point(a*x, a*y); }
        double norm() { return x*x + y*y; }
        bool operator < (const point &p) const{
            return x != p.x ? x + EPS < p.x : y + EPS < p.y;
        }
    };
    
    double dot(point a,point b) {
        return a.x*b.x + a.y*b.y;
    }
    double det(point a,point b) {
        return a.x*b.y - a.y*b.x;
    }
    typedef vector<point>polygon;
    int contain( polygon g, point p) {//1代表在多边形内,0代表在多边形外,2在边上
        int n = g.size(); bool x = 0;
        for (int i = 0; i < n;i++) {
            point a = g[i] - p, b = g[(i + 1) % n] - p;
            if (fabs(det(a, b)) < EPS&&dot(a, b) < EPS)return 2;
            if (a.y > b.y)swap(a, b);
            if (a.y<EPS&&b.y>EPS&&det(a, b) > EPS)x = !x;
        }
        return x ? 1 : 0;
    }
    int ccw(point a,point b,point c) {//顺时针转还是逆时针转
        point x = b - a, y = c - a;
        if(det(x, y)>EPS)return 1;
        if (det(x, y) < -EPS)return -1;
        if (dot(a, b) < -EPS)return 2;
        if (a.norm() < b.norm())return -2;
        return 0;
    }
    
    int main() {
        int t; scanf("%d",&t);
        while (t--) {
            polygon T1, T2;
            T1.resize(3); T2.resize(3);
            for (int i = 0; i < 3; i++)
                scanf("%lf%lf",&T1[i].x,&T1[i].y);
            for (int i = 0; i < 3; i++)
                scanf("%lf%lf", &T2[i].x, &T2[i].y);
            bool is_wai = 0, is_nei = 0,flag=0;
            for (int i = 0; i < 3;i++) {
                int c = contain(T1, T2[i]);
                if (c==1) {
                    is_nei = 1;
                }
                else if(c==0)is_wai = 1;
                else { flag = 1; break; }//在边上一定相交
            }
            if (flag||(is_wai&&is_nei)) { puts("intersect"); continue; }
            if (is_nei && !is_wai) { puts("contain"); }
            else {
                is_nei = 0,is_wai=0;
                for (int i = 0; i < 3;i++) {
                    int c = contain(T2,T1[i]);
                    if (c == 1)is_nei = 1;
                    if (c == 0)is_wai = 1;
                }
                if (is_nei&&!is_wai)puts("contain");
                if (is_nei&&is_wai)puts("intersect");
                else {//六个点都在另外三角形的外部,判断是否有边相交的情况
                    bool is_intersect = 0;
                    point a = T1[0], b = T1[1];
                    for (int i = 0; i < 3; i++) {
                        point c = T2[i], d = T2[(i + 1) % 3];
                        if (ccw(a, b, c)*ccw(a, b, d) <= 0 && ccw(c, d, a)*ccw(c, d, b) <= 0){
                            is_intersect = 1; break;
                         }
                    }
                    if (is_intersect)puts("intersect");
                    else puts("disjoint");
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    SAX解析XML笔记
    使用 Angular 2 来创建FlexGrid控件
    算法-快速排序(优雅版)
    使用泛型简化动态代理
    Java泛型概述
    POI-PPT官方文档
    Java 利用POI操作PPT
    Java8学习笔记(九)--日期/时间(Date Time)API指南
    Java8学习笔记(八)--方法引入的补充
    Android WebView加载本地html并实现Java与JS交互
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/8781984.html
Copyright © 2020-2023  润新知