Miền đồ thị #2

Xem PDF



Dạng bài
Điểm: 10 (p) Thời gian: 1.0s Bộ nhớ: 256M Input: bàn phím Output: màn hình

Cho tọa độ \(3\) đỉnh của \(1\) tam giác, xác định số miền trên đồ thị mà tam giác đó đè lên.

Input

  • Gồm 3 dòng, mỗi dòng là 2 số nguyên \(x, y\) (\(-10^{4} \leq x, y \leq 10^{4}\)) là 1 đỉnh của tam giác.

Output

  • Gồm 1 dòng là tổng số miền trên đồ thị mà tam giác đó đè lên

Example

Test 1
Input
0 0
1 1
0 1
Output
1

Bình luận


  • 1
    lehongduc    3:05 p.m. 8 Tháng 10, 2024 chỉnh sửa 8
    Hint

    Bài này ta chia làm 3 phần, tượng trưng cho 3 trường hợp của bài toán:
    \(1.\) Vị trí của 3 điểm ( có thể xem lại ở bài này Miền đồ thị #1
    \(2.\) Đoạn thẳng được tạo ra từ 2 điểm có x,y!=0
    \(3.\) Đoạn thẳng dc tạo ra từ 2 điểm có x=0 hoặc y=0 hoặc cả 2
    Để tránh việc trùng giá trị của các miền thỏa mãn vào 1 set
    Nếu trường hợp nào thỏa mãn thì thêm tên của miền (1,2,3,4) vào set
    Đoạn cuối chỉ cần xuất kích thước của set là được!
    Giải từng phần:

    Phần 1

    Gồm 4 trường hợp:
    \(-\) x>0 và y>0 thì điểm thuộc miền I
    \(-\) x<0 và y>0 thì điểm thuộc miền II
    \(-\) x<0 và y<0 thì điểm thuộc miền III
    \(-\) x>0 và y<0 thì điểm thuộc miền IV

    Như bạn có thể thấy, trường hợp 1 bài này khác với bài Miền đồ thị #1 ở một chỗ
    Trong bài kia, nếu một điểm có tọa đô (0;0) thì nó dc tính đang đứng ở cả 4 miền
    Còn ở đây nếu nó ở trên trục tạo độ thì nó không được tính là ở trên miền nào cả
    Vậy nên ta chia vị trí của đường thẳng thành 2 loại, loại 2 điểm có tọa độ bằng 0 và không có tọa độ bằng 0

    code c++
    void ham(db x,db y)
    {
        if(x==0||y==0) return;
        if(x>0)
        {
            if(y>0) mang.insert(1);
            else mang.insert(4);
        }
        else
        {
            if(y>0) mang.insert(2);
            else mang.insert(3);
        }
    }
    
    phần 2

    Ta nhận thầy rằng: Nếu 2 điểm ở 2 miền cạnh nhau thì khi nối 2 điểm với nhau sẽ không có thêm bất kì miền nào được "đi qua"
    Vậy nên ta chỉ xét trường hợp 2 điểm ở 2 miền không cạnh nhau
    VD: miền 2 và 4, miền 1 và 3

    Ta nhận thấy rằng nếu nối điểm đang xét với gốc tọa độ O và kéo dài, có 2 trường hợp và mỗi trường hợp chia làm 3 trường hợp nhỏ hơn:
    \(-\) Trường hợp điểm đang xét nằm ở miền 1 hoặc 3:
    \(+\) Trường hợp 1: Nếu điểm còn lại ở trên đường thẳng mới vẽ thì không có chuyện gì xảy ra
    \(+\) Trường hợp 2: Điểm còn lại nằm ở bên trên đường thẳng thì đường thẳng nối giữa 2 điểm chắc chắn sẽ đi qua miền 2
    \(+\) Trường hợp 3: Điểm còn lại nằm ở dưới đường thẳng thì đường thẳng nối giữa 2 điểm chắc chắn sẽ đi qua miền 4

    \(-\) Trường hợp điểm đang xét nằm ở miền 2 hoặc 4:
    \(+\) Trường hợp 1: Nếu điểm còn lại ở trên đường thẳng mới vẽ thì không có chuyện gì xảy ra
    \(+\) Trường hợp 2: Điểm còn lại nằm ở bên trên đường thẳng thì đường thẳng nối giữa 2 điểm chắc chắn sẽ đi qua miền 1
    \(+\) Trường hợp 3: Điểm còn lại nằm ở dưới đường thẳng thì đường thẳng nối giữa 2 điểm chắc chắn sẽ đi qua miền 3

    Vậy làm cách nào để biết một điểm nằm ở, trên hay dưới đoạn thẳng?
    Đến đây ta phải sử dụng đến lí thuyết của đồ thị của phương trình bậc nhất
    Ta có 2 cách:

    cách 1

    Ta có:
    Phương trình của đường thằng nối từ điểm đang xét đến gốc O (d1) là: ax+b=y
    ta có (d1) đi qua điểm (0;0)
    => a.0+b=0
    <=> b=0
    => phương trình của (d1) là ax=y
    <=> a=x/y

    Gọi a là của biểu diễn giữa điểm đang xét, a' là của biểu diễn giữa điểm nối với điểm O

    Ta có: với 2 biểu diễn của phương trình bậc nhất: nếu 2 đường thẳng có a=a' và b=b' thì 2 biểu diễn trùng nhau với ở đây b=0 nên nếu a=a' thì 2 biểu diễn trùng nhau hay điểm còn lại trùng với đường thẳng của điểm đang xét
    Tương tự với 2 trường hợp còn lại ta có:
    Nếu a<a' thì điểm nằm trên đường thẳng Nếu a>a' thì điểm nằm dưới đường thẳng
    Đây là đối với đường thẳng của 2 điểm ở miền I và III
    Còn với 2 điểm ở miền II và IV thì ngược lại

    Ta có thể phân biệt 2 điểm đang ở 2 miền nào bằng cách, nếu a của đường thẳng nối giữa điểm đang xét và O âm thì điểm đang xét nằm ở miền II và IV
    Và ngược lại

    Kết hợp những thứ ở trên ta có:

    • Đối với a>0 -2 điểm thuộc miền I và III-:
      +Nếu a=a' không có chuyện gì xảy ra

      +Nếu a<a' đi qua miền 2

      +Nếu a>a' đi qua miền 4

    • đối với a<0 -2 điểm thuộc miền II và IV-:
      +Nếu a=a' không có chuyện gì xảy ra

      +Nếu a<a' đi qua miền 1

      +Nếu a>a' đi qua miền 3

    code C++
    ```
    void ham1(db x1,db y1,db x2,db y2)
    {
        db a,b;
        a=y1/x1;
        b=y2/y1;
        if(a>0)
        {
            if(b>a) mang.insert(2);
            else if(b<a) mang.insert(4);
        }
        else
        {
            if(b>a) mang.insert(1);
            else if(b<a) mang.insert(3);
        }
    }
    ```
    
    cách 2

    ta cũng nối điểm đang xét và O (d1)
    => ax+b=y
    <=> ax=y
    ta kẻ thêm một đường nữa để nối giữa điểm còn lại, đường này song song với (d1)
    ta có b ở (d1) = 0
    còn ở đường (d2), ta có a=a' vì 2 đường này song song với nhau
    => ax+b'=y
    <=> b'=y-ax
    ta nhận thấy với a>0 thì điểm thuộc miền I và III
    nếu b'>b=0 thì điểm ở trên (d1)
    nếu b'=b=0 điểm nằm ở (d1)
    nếu b'<b=0 điểm nằm dưới (d1)
    ngược lại với a<0 hay điểm thuộc miền II và IV

    code C++
    void ham1(db x1,db y1,db x2,db y2)
    {
        db a,b;
        a=y1/x1;
        b=y2-a*x2;
        if(a>0)
        {
            if(b>0) mang.insert(2);
            else if(b<0) mang.insert(4);
        }
        else
        {
            if(b>0) mang.insert(1);
            else if(b<0) mang.insert(3);
        }
    }
    
    phần 3

    Còn nữa

    Đây là cách làm, suy nghĩ của mình, bạn nào có cách ngắn gọn hơn thì bình luận dưới nhé =)

    • 2 bình luận nữa