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

  • dangnguyennhatkhoi0707 6:11 p.m. 13 Tháng 1, 2025

    • 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é =)

      • lehongduc 12:04 a.m. 4 Tháng 10, 2024 chỉnh sửa 4

        .

        • dangnguyennhatkhoi0707 1:18 p.m. 29 Tháng 9, 2024

          cho code nè