https://www.acmicpc.net/problem/6439



사각형과 선분의 교차 여부를 판단해주면 된다.


사각형 정점의 입력이 두 점이 주어지는데, 위치가 정해져있지 않다. x, y좌표들을 적절하게 대소비교해서 정점 네개를 잡아서


사각형을 만들어줘야 한다.



한 점만 공유해도 교차하는 것으로 간주한다고 했기 때문에, ccw 결과에 0을 포함시켜도 좋다.


사각형의 네 변과 선분을 각각 교차판정 해주고, 사각형의 내부에 선분이 존재하는지 확인한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<iostream>
#include<algorithm>
 
using namespace std;
typedef long long ll;
struct PT {
    ll x, y;
};
 
int ccw(int x1, int y1, int x2, int y2, int x3, int y3) {
    ll ret = (x1*y2 + x2 * y3 + x3 * y1) - (y1*x2 + y2 * x3 + y3 * x1);
    if (ret < 0return -1;
    else if (ret > 0return 1;
    else return 0//일직선 상에 위치
}
 
bool isCross(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
    if (ccw(x1, y1, x2, y2, x3, y3) * ccw(x1, y1, x2, y2, x4, y4) <= 0 &&
        ccw(x3, y3, x4, y4, x1, y1) * ccw(x3, y3, x4, y4, x2, y2) <= 0) {
        //아예 멀리 떨어져 있는 경우
        if ((x1 < x3 && x1 < x4 && x2 < x3 && x2 < x4) ||
            (x3 < x1 && x3 < x2 && x4 < x1 && x4 < x2)) return false;
        if ((y1 < y3 && y1 < y4 && y2 < y3 && y2 < y4) ||
            (y3 < y1 && y3 < y2 && y4 < y1 && y4 < y2)) return false;
        return true;
    }
    return false;
}
 
int main(void) {
    int T;
    cin >> T;
    while (T--) {
        PT l1, l2, r1, r2, r3, r4;
        cin >> l1.x >> l1.y >> l2.x >> l2.y;
        ll tmpx1, tmpx2, tmpy1, tmpy2;
        cin >> tmpx1 >> tmpy1 >> tmpx2 >> tmpy2; //사각형 좌표는 의미없는 순서로 들어옴
 
        r1 = { min(tmpx1, tmpx2), min(tmpy1, tmpy2) }; 
        r2 = { min(tmpx1, tmpx2), max(tmpy1, tmpy2) };
        r3 = { max(tmpx1, tmpx2), min(tmpy1, tmpy2) };
        r4 = { max(tmpx1, tmpx2), max(tmpy1, tmpy2) };
 
        if (isCross(l1.x, l1.y, l2.x, l2.y, r1.x, r1.y, r2.x, r2.y) ||
            isCross(l1.x, l1.y, l2.x, l2.y, r2.x, r2.y, r4.x, r4.y) ||
            isCross(l1.x, l1.y, l2.x, l2.y, r4.x, r4.y, r3.x, r3.y) ||
            isCross(l1.x, l1.y, l2.x, l2.y, r3.x, r3.y, r1.x, r1.y)) {
            cout << "T" << '\n'//하나라도 교차하면
        }
        else {
            //내부에 있거나 안만나거나 (isCross false)
            if ((r1.x < l1.x && r1.x < l2.x && l1.x < r3.x && l2.x < r3.x) &&
                (r1.y < l1.y && r1.y < l2.y && l1.y < r4.y && l2.y < r4.y)) {
                cout << "T" << '\n'//사각형의 내부에 선분이 존재해서 만나지 않은 경우
            }
            else
                cout << "F" << '\n';
        }
    }
    return 0;
}
cs




복습



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//좌표값 -> 정수이면서 크기 조건이 없음
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
struct POT {
    ll x, y;
    POT operator - (POT a) { return{x-a.x, y-a.y}; }
};
 
ll ccw(POT p1, POT p2) {
    ll ret = p1.x*p2.y - p1.y*p2.x;
    if (ret == 0return 0;
    else if (ret > 0return 1;
    else return -1;
}
 
ll ccw(POT p1, POT p2, POT p3) {
    return ccw(p2 - p1, p3 - p1);
}
bool isCross(POT p1, POT p2, POT p3, POT p4) {
    if (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
        ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0) {
        if ((p1.x < p3.x && p1.x < p4.x && p2.x < p3.x && p2.x < p4.x) ||
            (p3.x < p1.x && p3.x < p2.x && p4.x < p1.x && p4.x < p2.x)) return false;
        if ((p1.y < p3.y && p1.y < p4.y && p2.y < p3.y && p2.y < p4.y) ||
            (p3.y < p1.y && p3.y < p2.y && p4.y < p1.y && p4.y < p2.y)) return false;
        else
            return true;
    }    
    return false//둘다 0이하 아니면 안 만남
}
 
int main(void) {
    int T;
    cin >> T;
    while (T--) {
        POT st, en;
        cin >> st.x >> st.y >> en.x >> en.y;
        ll x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        ll xmin, xmax, ymin, ymax;
        xmin = min(x1, x2);
        ymin = min(y1, y2);
        xmax = max(x1, x2);
        ymax = max(y1, y2);
        
        POT p[5];
        p[0= { xmin, ymin };
        p[1= { xmax, ymin };
        p[2= { xmax, ymax };
        p[3= { xmin, ymax };
        p[4= p[0];
 
        //1. 교차하면 T
        bool endFlag = false;
        for (int i = 0; i < 4; i++)
            if (isCross(st, en, p[i], p[i + 1])) {
                cout << "T" << '\n';
                endFlag = true;
                break;
            }
        if (endFlag) continue;
 
        //2. 교차하지 않았으나, 사각형 내부에 선분이 존재하면 T
        if ((xmin < st.x && xmin < en.x && st.x < xmax && en.x < xmax) &&
            (ymin < st.y && ymin < en.y && st.y < ymax && en.y < ymax)) {
            cout << "T" << '\n';
            continue;
        }
        
        //3. 나머지
        cout << "F\n";
    }
}
cs


'알고리즘 문제 풀이 > 백준 온라인 저지' 카테고리의 다른 글

백준 10255 교차점 C++  (0) 2019.08.11
백준 1485 정사각형 C++  (0) 2019.08.11
백준 2162: 선분 그룹 C++  (0) 2019.08.11
백준 2166 다각형의 면적 C++  (0) 2019.08.10
백준 11758 CCW C++  (0) 2019.08.10

+ Recent posts