CSES - Aalto Competitive Programming 2024 - wk10 - Homework - Results
Submission details
Task:Line Segment Intersection
Sender:minghao
Submission time:2024-11-13 19:16:54 +0200
Language:C++ (C++20)
Status:READY
Result:ACCEPTED
Test results
testverdicttime
#1ACCEPTED0.22 sdetails
#2ACCEPTED0.23 sdetails
#3ACCEPTED0.25 sdetails
#4ACCEPTED0.26 sdetails
#5ACCEPTED0.00 sdetails
#6ACCEPTED0.00 sdetails

Compiler report

input/code.cpp: In function 'void Test()':
input/code.cpp:128:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  128 |     freopen("temp\\in.txt", "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
input/code.cpp: In member function 'void Point::Input()':
input/code.cpp:19:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   19 |         scanf("%lld%lld", &x_, &y_);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~

Code

#include <bits/stdc++.h>
typedef long long LL;
using namespace std;

inline int Sign(const LL& x)
{
    if(x == 0)          return 0;
    if(x < 0)           return -1;
    else                return 1;
}
 
struct Point
{
    LL x_, y_;
    Point(){}
    Point(LL x, LL y): x_(x), y_(y) {}

    void Input() {
        scanf("%lld%lld", &x_, &y_);
    }
    void Output() {
        printf("%lld %lld", x_, y_);
    }
 
    bool operator == (const Point& P)   const {
        return Sign(x_ - P.x_) == 0 && Sign(y_ - P.y_) == 0;
    }
    bool operator < (const Point& P)    const {
        return Sign(x_ - P.x_) == 0? Sign(y_ - P.y_)<0 : x_<P.x_;
    }
    LL operator ^ (const Point& P)  const {
        return x_*P.y_ - y_*P.x_;
    }
    LL operator * (const Point& P)  const {
        return x_*P.x_ + y_*P.y_;
    }
    Point operator + (const Point& P)   const {
        return Point(x_+P.x_, y_+P.y_);
    }
    Point operator - (const Point& P)   const {
        return Point(x_-P.x_, y_-P.y_);
    }
    Point operator * (const LL& k)  const {
        return Point(x_*k, y_*k);
    }
    Point operator / (const LL& k)  const {
        return Point(x_/k, y_/k);
    }
 
    LL len() {
        return hypot(x_, y_);
    }
    LL dis(Point P) {
        return hypot(x_ - P.x_, y_ - P.y_);
    }

    Point Trunc(LL r) 
    {
        LL l = len();
        if(!Sign(l)) return *this;
        r /= l;
        return Point(x_*r, y_*r);
    }
    // Point Rotate(Point p, LL angle) 
    // {
    //     Point v = (*this) - p;
    //     LL c = cos(angle), s = sin(angle);
    //     return Point(p.x_ + c*v.x_ - s*v.y_, p.y_ + s*v.x_ + c*v.y_);
    // }
};
 
struct Line
{
    Point u_, v_;
    Line(){}
    Line(Point u, Point v): u_(u), v_(v) {}
    // Line(Point p, LL angle) 
    // {
    //     u_ = p;
    //     if(Sign(angle - PI/2) == 0) {
    //         v_ = (u_ + Point(0, 1));
    //     } else {
    //         v_ = (u_ + Point(1, tan(angle)));
    //     }
    // }

    LL len() {
        return u_.dis(v_);
    }
    // LL ang() {
    //     LL k = atan2(v_.y_ - u_.y_, v_.x_ - u_.x_);
    //     if(Sign(k) < 0)         k += PI;
    //     if(Sign(k - PI) == 0)   k -= PI;
    //     return k;
    // }

    bool OnSeg(Point p) {
        return Sign((p - u_)^(v_ - u_)) == 0 && Sign((p - u_)*(p - v_)) <= 0;
    }
    // 0(On) 2(R) 1(L)
    int Relation(Point p) 
    {
        int c = Sign((p - u_)^(v_ - u_));
        if(c < 0)       return 1;
        else if(c > 0)  return 2;
        else            return 0;
    }
    // 2(true) 1(false) 0 (no)
    int SegCrossSeg(Line l)
    {
        int d1 = Sign((v_ - u_)^(l.u_ - u_));
        int d2 = Sign((v_ - u_)^(l.v_ - u_));
        int d3 = Sign((l.v_ - l.u_)^(u_ - l.u_));
        int d4 = Sign((l.v_ - l.u_)^(v_ - l.u_));

        if((d1^d2) == -2 && (d3^d4) == -2)  return 2;
        return  (d1 == 0 && Sign((l.u_ - u_)*(l.u_ - v_)) <= 0) ||
                (d2 == 0 && Sign((l.v_ - u_)*(l.v_ - v_)) <= 0) ||
                (d3 == 0 && Sign((u_ - l.u_)*(u_ - l.v_)) <= 0) ||
                (d4 == 0 && Sign((v_ - l.u_)*(v_ - l.v_)) <= 0);
    }
};



void Test()
{
    freopen("temp\\in.txt", "r", stdin);
}
int main()
{
    // Test();
    int n;
    cin >> n;
    Line A, B;
    while(n--)
    {
        A.u_.Input();
        A.v_.Input();
        B.u_.Input();
        B.v_.Input();
        if(A.SegCrossSeg(B))
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }

    return 0;
}

Test details

Test 1

Verdict: ACCEPTED

input
100000
9 7 1 8 8 -5 0 2
10 1 -1 2 -4 1 -7 3
10 2 -8 6 1 2 2 -1
-10 1 9 -7 4 -3 -5 0
...

correct output
NO
NO
NO
NO
NO
...

user output
NO
NO
NO
NO
NO
...

Test 2

Verdict: ACCEPTED

input
100000
81 745 -967 768 -451 -490 -454...

correct output
NO
NO
YES
NO
YES
...

user output
NO
NO
YES
NO
YES
...

Test 3

Verdict: ACCEPTED

input
100000
492853 -452834 -657156 -282543...

correct output
YES
YES
NO
YES
YES
...

user output
YES
YES
NO
YES
YES
...

Test 4

Verdict: ACCEPTED

input
100000
788522666 939776556 -831492125...

correct output
NO
NO
NO
NO
NO
...

user output
NO
NO
NO
NO
NO
...

Test 5

Verdict: ACCEPTED

input
1
1 6 6 6 4 4 1000000000 1000000...

correct output
YES

user output
YES

Test 6

Verdict: ACCEPTED

input
1
-1000000000 1000000000 9999999...

correct output
NO

user output
NO