Bao lồi nâng cao và kỹ thuật xoay compa
Bài Diện tích đa giác và điểm nguyên đã giới thiệu bao lồi và thuật toán chuỗi đơn điệu. Bài này đi tiếp: dựng bao lồi đúng trong mọi trường hợp đặc biệt, rồi khai thác bao lồi bằng kỹ thuật xoay compa (rotating calipers) để giải các bài “xa nhất, hẹp nhất, lớn nhất” chỉ trong thời gian tuyến tính, và các thao tác trên đa giác lồi: tìm điểm, cắt, giao, cộng.
Các bạn cần nắm vững bài Điểm, khoảng cách và tích có hướng và bài Diện tích đa giác.
Bao lồi trong mọi trường hợp
Phần tiêu đề “Bao lồi trong mọi trường hợp”Ký hiệu cross(O, A, B) là tích có hướng của OA và OB: dương nếu B nằm bên trái tia OA, âm nếu bên phải, bằng 0 nếu thẳng hàng.
def cross(o, a, b): return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])
def bao_loi(p, giu_thang_hang=False): """Các đỉnh theo chiều ngược kim đồng hồ, bắt đầu từ điểm có (x, y) nhỏ nhất.""" p = sorted(set(p)) # bỏ điểm trùng if len(p) <= 2: return p def nua(ds): h = [] for q in ds: while len(h) >= 2: c = cross(h[-2], h[-1], q) if c < 0 or (c == 0 and not giu_thang_hang): h.pop() else: break h.append(q) return h duoi, tren = nua(p), nua(p[::-1]) if giu_thang_hang and len(duoi) == len(p): # mọi điểm thẳng hàng return p return duoi[:-1] + tren[:-1]
print(bao_loi([(0, 0), (2, 0), (2, 2), (0, 2), (1, 1), (1, 0)]))# [(0, 0), (2, 0), (2, 2), (0, 2)]print(bao_loi([(0, 0), (2, 0), (2, 2), (0, 2), (1, 1), (1, 0)], True))# [(0, 0), (1, 0), (2, 0), (2, 2), (0, 2)]#include <iostream>#include <vector>#include <algorithm>using namespace std;
struct Diem { long long x, y; bool operator<(const Diem &o) const { return x < o.x || (x == o.x && y < o.y); } bool operator==(const Diem &o) const { return x == o.x && y == o.y; }};
long long cross(const Diem &o, const Diem &a, const Diem &b) { return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);}
vector<Diem> baoLoi(vector<Diem> p, bool giuThangHang = false) { sort(p.begin(), p.end()); p.erase(unique(p.begin(), p.end()), p.end()); // bỏ điểm trùng int n = p.size(); if (n <= 2) return p; auto nua = [&](const vector<Diem> &ds) { vector<Diem> h; for (const Diem &q : ds) { while (h.size() >= 2) { long long c = cross(h[h.size() - 2], h.back(), q); if (c < 0 || (c == 0 && !giuThangHang)) h.pop_back(); else break; } h.push_back(q); } return h; }; vector<Diem> duoi = nua(p); vector<Diem> nguoc(p.rbegin(), p.rend()); vector<Diem> tren = nua(nguoc); if (giuThangHang && (int)duoi.size() == n) return p; // mọi điểm thẳng hàng duoi.pop_back(); tren.pop_back(); duoi.insert(duoi.end(), tren.begin(), tren.end()); return duoi;}
int main() { vector<Diem> p = {{0, 0}, {2, 0}, {2, 2}, {0, 2}, {1, 1}, {1, 0}}; for (auto &d : baoLoi(p)) cout << d.x << " " << d.y << endl; return 0;}Ba chỗ hay sai:
| Trường hợp | Cách xử lý |
|---|---|
| Điểm trùng nhau | Bỏ trùng sau khi sắp xếp |
| Mọi điểm thẳng hàng | Bỏ điểm thẳng hàng thì còn 2 đầu mút; giữ điểm thẳng hàng thì nửa dưới đã chứa tất cả, trả về luôn |
| Cần giữ điểm nằm giữa cạnh | Chỉ bỏ khi tích có hướng nhỏ hơn 0 |
Lưu ý: với tọa độ tới 109, tích có hướng tới 8 × 1018, sát giới hạn long long
(khoảng 9,2 × 1018). Không cộng dồn các tích có hướng (ví dụ tính diện tích) nếu tọa độ lớn như vậy.
Sắp xếp theo góc chính xác
Phần tiêu đề “Sắp xếp theo góc chính xác”Nhiều thuật toán cần sắp các điểm theo góc quanh một tâm. Dùng atan2 thì hai hướng rất gần nhau có thể cho
cùng một số thực. So sánh chính xác bằng số nguyên:
- Chia mặt phẳng thành nửa trên (y lớn hơn 0, hoặc y = 0 và x lớn hơn 0) và nửa dưới. Nửa trên đứng trước.
- Trong cùng một nửa, a đứng trước b khi tích có hướng a × b lớn hơn 0.
Bước 1 là bắt buộc: trên cả mặt phẳng, “a × b lớn hơn 0” không có tính bắc cầu (đi hết một vòng sẽ quay lại).
Xoay compa
Phần tiêu đề “Xoay compa”Hãy tưởng tượng kẹp bao lồi giữa hai đường thẳng song song (hai càng của compa) rồi xoay một vòng. Mỗi lần một càng áp sát một cạnh (i, i + 1), càng kia chạm vào đỉnh j xa cạnh đó nhất. Quan sát quan trọng:
Khi i đi quanh bao lồi theo chiều ngược kim đồng hồ, đỉnh xa nhất j cũng chỉ đi tới, không bao giờ lùi.
Vậy chỉ cần hai con trỏ i, j cùng đi một vòng: tổng h bước thay vì h2.
def duong_kinh2(h): """Bình phương khoảng cách lớn nhất giữa hai đỉnh của đa giác lồi h (ngược chiều kim đồng hồ).""" d2 = lambda a, b: (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 k = len(h) if k <= 2: return d2(h[0], h[-1]) tot, j = 0, 1 for i in range(k): ni = (i + 1) % k while abs(cross(h[i], h[ni], h[(j + 1) % k])) > abs(cross(h[i], h[ni], h[j])): j = (j + 1) % k # j tiến tới đỉnh xa cạnh (i, ni) nhất tot = max(tot, d2(h[i], h[j]), d2(h[ni], h[j])) return totlong long d2(const Diem &a, const Diem &b) { return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);}
// Bình phương khoảng cách lớn nhất giữa hai đỉnh của đa giác lồi h (ngược chiều kim đồng hồ)long long duongKinh2(const vector<Diem> &h) { int k = h.size(); if (k <= 2) return d2(h[0], h[k - 1]); long long tot = 0; int j = 1; for (int i = 0; i < k; i++) { int ni = (i + 1) % k; while (llabs(cross(h[i], h[ni], h[(j + 1) % k])) > llabs(cross(h[i], h[ni], h[j]))) j = (j + 1) % k; // j tiến tới đỉnh xa cạnh (i, ni) nhất tot = max(tot, max(d2(h[i], h[j]), d2(h[ni], h[j]))); } return tot;}Cùng một khung cho nhiều bài:
| Bài toán | Ở mỗi cạnh (i, i + 1) cần | Kết quả |
|---|---|---|
| Đường kính (hai điểm xa nhất) | đỉnh j xa cạnh nhất | lớn nhất của khoảng cách j tới hai đầu cạnh |
| Bề rộng (khe hẹp nhất) | đỉnh j xa cạnh nhất | nhỏ nhất của khoảng cách từ j tới cạnh |
| Hình chữ nhật bao nhỏ nhất | thêm hai đỉnh có hình chiếu lên hướng cạnh lớn nhất, nhỏ nhất | rộng × dài (hoặc chu vi) nhỏ nhất |
| Tam giác lớn nhất | cố định i, cho j chạy, đỉnh thứ ba k chỉ tiến | h2 thay vì h3 |
Hai định lý đứng sau bảng trên: bề rộng nhỏ nhất và hình chữ nhật bao nhỏ nhất đều đạt khi một cạnh nằm trên một cạnh của bao lồi. Vì thế chỉ cần xét h hướng.
Điểm trong đa giác lồi: tìm kiếm nhị phân
Phần tiêu đề “Điểm trong đa giác lồi: tìm kiếm nhị phân”Với đa giác lồi h0, h1, …, hn - 1 (ngược chiều kim đồng hồ), các tia từ h0 chia đa giác thành n - 2 tam giác hình quạt. Điểm P:
- Nằm ngoài nếu ở bên phải tia h0h1 hoặc bên trái tia h0hn - 1.
- Tìm nhị phân tam giác (h0, hi, hi + 1) chứa hướng của P.
- Xét P với cạnh hihi + 1 để kết luận trong, trên biên hay ngoài.
Mỗi câu hỏi log n bước, thay vì n bước khi xét từng cạnh.
Cắt đa giác lồi
Phần tiêu đề “Cắt đa giác lồi”Giữ phần của đa giác lồi nằm bên trái đường thẳng có hướng AB: đi qua từng cạnh (P, Q),
- giữ P nếu P nằm bên trái hoặc trên đường thẳng;
- nếu P và Q ở hai phía, thêm giao điểm (tỉ lệ t = cP / (cP - cQ), với c là tích có hướng).
Kết quả vẫn là đa giác lồi. Từ thao tác này:
- Giao hai đa giác lồi = cắt đa giác thứ nhất lần lượt bởi mọi cạnh của đa giác thứ hai.
- Giao các nửa mặt phẳng = bắt đầu từ một hình vuông thật lớn, cắt lần lượt bởi từng nửa mặt phẳng.
Tổng Minkowski
Phần tiêu đề “Tổng Minkowski”Tổng Minkowski P + Q gồm mọi điểm p + q (cộng tọa độ). Với P, Q lồi, P + Q cũng lồi, và các cạnh của P + Q chính là các cạnh của P và Q, xếp theo góc. Bắt đầu từ tổng hai đỉnh thấp nhất, trộn hai dãy cạnh như trộn hai dãy đã sắp xếp (so sánh góc bằng tích có hướng): n + m bước.
Ví dụ: hình vuông + hình tròn bán kính r (coi như đa giác nhiều cạnh) cho hình vuông “bo góc”, chu vi tăng thêm 2πr. Đó chính là lý do sợi dây bao quanh các giếng tròn dài hơn chu vi bao lồi đúng 2πr.
Luyện tập
Phần tiêu đề “Luyện tập”Gồm 20 bài, chia thành 4 nhóm từ dễ đến khó. Mỗi bài có một dữ liệu kiểm tra: các bạn chạy chương trình của mình với dữ liệu đó rồi so với đáp số.
Nhóm 1. Dựng bao lồi trong mọi trường hợp
Phần tiêu đề “Nhóm 1. Dựng bao lồi trong mọi trường hợp”Bài 1. In bao lồi
Phần tiêu đề “Bài 1. In bao lồi”Dòng đầu là n (1 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 109, có thể trùng nhau, có thể thẳng hàng hết). In ra số đỉnh h của bao lồi, rồi h dòng là các đỉnh theo chiều ngược kim đồng hồ, bắt đầu từ đỉnh có x nhỏ nhất (nếu bằng nhau thì y nhỏ nhất). Không in các điểm nằm giữa một cạnh. Nếu mọi điểm thẳng hàng thì bao lồi là đoạn thẳng, in hai đầu mút; nếu mọi điểm trùng nhau thì in một điểm.
Ví dụ:
| Nhập | In ra |
|---|---|
60 02 02 20 21 11 0 | 40 02 02 20 2 |
Kiểm tra: nhập
83 1-2 40 05 5-1 -34 -20 62 2Bài 2. Số điểm trên biên
Phần tiêu đề “Bài 2. Số điểm trên biên”Dòng đầu là n (1 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm khác nhau (|x|, |y| ≤ 109). In ra số điểm nằm trên biên bao lồi (kể cả các điểm nằm giữa một cạnh).
Ví dụ:
| Nhập | In ra |
|---|---|
60 02 02 20 21 11 0 | 5 |
Kiểm tra: nhập
90 03 06 06 36 63 30 62 41 1Bài 3. Sắp xếp theo góc
Phần tiêu đề “Bài 3. Sắp xếp theo góc”Dòng đầu là n (1 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm khác gốc O (|x|, |y| ≤ 109). Sắp xếp các điểm theo góc tạo bởi tia Ox và tia từ O đến điểm, đo ngược chiều kim đồng hồ trong khoảng [0°, 360°); điểm cùng góc thì điểm gần O hơn đứng trước. In ra các điểm theo thứ tự đó.
Ví dụ:
| Nhập | In ra |
|---|---|
51 1-1 02 00 -32 2 | 2 01 12 2-1 00 -3 |
Kiểm tra: nhập
63 -1-2 -20 51 0-1 -1-4 3Bài 4. Bóc từng lớp vỏ
Phần tiêu đề “Bài 4. Bóc từng lớp vỏ”Dòng đầu là n (1 ≤ n ≤ 2000), n dòng sau là tọa độ nguyên các điểm khác nhau (|x|, |y| ≤ 106). Mỗi lần, bỏ đi tất cả các điểm nằm trên biên bao lồi của các điểm còn lại (kể cả điểm nằm giữa cạnh; nếu chỉ còn 1, 2 điểm hoặc các điểm thẳng hàng thì bỏ hết). In ra số lần bỏ cho tới khi hết điểm.
Ví dụ:
| Nhập | In ra |
|---|---|
90 04 04 40 41 13 12 32 22 0 | 3 |
Kiểm tra: nhập
121 -50 -26 36 01 -1-4 -26 41 -4-5 54 4-5 6-2 4Bài 5. Dây bao quanh các giếng tròn
Phần tiêu đề “Bài 5. Dây bao quanh các giếng tròn”Dòng đầu có n và r (1 ≤ n ≤ 105, 1 ≤ r ≤ 104). n dòng sau là tâm của n cái giếng tròn bán kính r (tọa độ nguyên, |x|, |y| ≤ 106). Căng một sợi dây bao quanh tất cả các giếng. In ra độ dài sợi dây, làm tròn 3 chữ số sau dấu phẩy.
Ví dụ:
| Nhập | In ra |
|---|---|
4 10 04 04 30 3 | 20.283 |
Kiểm tra: nhập
10 331 -1430 -5-20 31-9 -717 -4-29 41-7 -57 428 -49-3 9Nhóm 2. Xoay compa
Phần tiêu đề “Nhóm 2. Xoay compa”Bài 6. Hai điểm xa nhau nhất
Phần tiêu đề “Bài 6. Hai điểm xa nhau nhất”Dòng đầu là n (2 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 109). In ra bình phương khoảng cách lớn nhất giữa hai điểm.
Ví dụ:
| Nhập | In ra |
|---|---|
40 03 00 41 1 | 25 |
Kiểm tra: nhập
12-51 7545 3987 -91-73 1986 -427 -99-89 -917 7068 5270 33-11 7071 76Bài 7. Khe hẹp nhất
Phần tiêu đề “Bài 7. Khe hẹp nhất”Dòng đầu là n (3 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 106, không phải tất cả thẳng hàng). Tìm khoảng cách nhỏ nhất giữa hai đường thẳng song song kẹp tất cả các điểm ở giữa (bề rộng của tập điểm). In ra kết quả làm tròn 3 chữ số sau dấu phẩy.
Ví dụ:
| Nhập | In ra |
|---|---|
40 04 04 20 2 | 2.000 |
Kiểm tra: nhập
1291 -2927 -74-72 4049 -3936 -4320 3736 -90-27 -5554 -70-61 43-4 -89-18 10Bài 8. Hộp chữ nhật nhỏ nhất
Phần tiêu đề “Bài 8. Hộp chữ nhật nhỏ nhất”Dòng đầu là n (3 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 104, không phải tất cả thẳng hàng). Hình chữ nhật (có thể đặt nghiêng) chứa tất cả các điểm có diện tích nhỏ nhất là bao nhiêu? In ra kết quả làm tròn 3 chữ số sau dấu phẩy.
Ví dụ:
| Nhập | In ra |
|---|---|
40 02 24 02 -2 | 8.000 |
Kiểm tra: nhập
12-74 -48-10 -7197 26-76 2759 -80-66 -1634 -4722 -6162 76-24 7849 -28-74 94Bài 9. Hộp chữ nhật có chu vi nhỏ nhất
Phần tiêu đề “Bài 9. Hộp chữ nhật có chu vi nhỏ nhất”Dòng đầu là n (3 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 104, không phải tất cả thẳng hàng). Hình chữ nhật (có thể đặt nghiêng) chứa tất cả các điểm có chu vi nhỏ nhất là bao nhiêu? In ra kết quả làm tròn 3 chữ số sau dấu phẩy.
Ví dụ:
| Nhập | In ra |
|---|---|
40 02 24 02 -2 | 11.314 |
Kiểm tra: nhập
1210 68-25 -7149 -61-2 9424 -3282 75-18 9363 24-1 734 1967 5445 77Bài 10. Tam giác lớn nhất với nhiều điểm
Phần tiêu đề “Bài 10. Tam giác lớn nhất với nhiều điểm”Dòng đầu là n (3 ≤ n ≤ 5000), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 108). Chọn 3 điểm tạo tam giác có diện tích lớn nhất. In ra hai lần diện tích đó.
Ví dụ:
| Nhập | In ra |
|---|---|
50 04 04 40 42 2 | 16 |
Kiểm tra: nhập
12-85 9494 -50-77 42-4 -594 84-5 4466 982 9946 -5055 -88-93 8881 91Nhóm 3. Đa giác lồi: câu hỏi, cắt, giao, tổng
Phần tiêu đề “Nhóm 3. Đa giác lồi: câu hỏi, cắt, giao, tổng”Bài 11. Nhiều điểm trong đa giác lồi
Phần tiêu đề “Bài 11. Nhiều điểm trong đa giác lồi”Dòng đầu là n (3 ≤ n ≤ 105), n dòng sau là các đỉnh của một đa giác lồi theo chiều ngược kim đồng hồ (không có ba đỉnh thẳng hàng, |x|, |y| ≤ 109). Dòng tiếp là Q (Q ≤ 105), Q dòng sau mỗi dòng là một điểm. Với mỗi điểm in ra TRONG, BIEN hoặc NGOAI.
Ví dụ:
| Nhập | In ra |
|---|---|
40 04 04 40 442 24 15 50 0 | TRONGBIENNGOAIBIEN |
Kiểm tra: nhập
7-9 1-6 -73 -99 -26 73 9-8 56-6 15-12 -715 -13-7 3-1 -10-9 1Bài 12. Cắt đa giác lồi bằng một nhát
Phần tiêu đề “Bài 12. Cắt đa giác lồi bằng một nhát”Dòng đầu là n (3 ≤ n ≤ 105), n dòng sau là các đỉnh của một đa giác lồi theo chiều ngược kim đồng hồ (tọa độ nguyên, |x|, |y| ≤ 104). Dòng cuối có 4 số nguyên xA, yA, xB, yB (A khác B). Cắt đa giác bằng đường thẳng AB. In ra diện tích phần nằm bên trái đường thẳng có hướng từ A đến B, làm tròn 3 chữ số sau dấu phẩy.
Ví dụ:
| Nhập | In ra |
|---|---|
40 04 04 40 40 1 4 3 | 8.000 |
Kiểm tra: nhập
7-15 1218 -819 -319 515 136 18-13 14-19 -16 4 11Bài 13. Giao của hai đa giác lồi
Phần tiêu đề “Bài 13. Giao của hai đa giác lồi”Dòng đầu là n, n dòng sau là các đỉnh của đa giác lồi thứ nhất; tiếp theo là m và m đỉnh của đa giác lồi thứ hai (3 ≤ n, m ≤ 1000, cả hai theo chiều ngược kim đồng hồ, tọa độ nguyên |x|, |y| ≤ 104). In ra diện tích phần chung của hai đa giác, làm tròn 3 chữ số sau dấu phẩy.
Ví dụ:
| Nhập | In ra |
|---|---|
40 04 04 40 442 26 26 62 6 | 4.000 |
Kiểm tra: nhập
6-19 04 -1910 -1714 13-1 19-8 186-13 7-8 -1017 -1325 -11 22-9 15Bài 14. Tổng Minkowski
Phần tiêu đề “Bài 14. Tổng Minkowski”Cho hai đa giác lồi P (n đỉnh) và Q (m đỉnh), mỗi đa giác theo chiều ngược kim đồng hồ, không có ba đỉnh thẳng hàng (3 ≤ n, m ≤ 105, tọa độ nguyên |x|, |y| ≤ 108). Tổng Minkowski P + Q là tập mọi điểm (px + qx, py + qy) với p thuộc P, q thuộc Q. In ra hai lần diện tích của P + Q. Dữ liệu vào: dòng n, n đỉnh, dòng m, m đỉnh.
Ví dụ:
| Nhập | In ra |
|---|---|
40 01 01 10 130 02 00 2 | 14 |
Kiểm tra: nhập
6-93 35-90 -42-11 -9996 2753 84-88 455-32 -629 -1331 -9-13 30-32 5Bài 15. Vùng an toàn
Phần tiêu đề “Bài 15. Vùng an toàn”Một vùng đất hình vuông có |x|, |y| ≤ 105. Có n đường thẳng (1 ≤ n ≤ 2000), mỗi đường cho bởi hai điểm nguyên A, B khác nhau (|x|, |y| ≤ 104); vùng an toàn phải nằm bên trái (hoặc trên) mọi đường thẳng có hướng từ A đến B. Dòng đầu là n, mỗi dòng sau có 4 số xA, yA, xB, yB. In ra diện tích vùng an toàn (phần của hình vuông thỏa mọi điều kiện), làm tròn 3 chữ số sau dấu phẩy.
Ví dụ:
| Nhập | In ra |
|---|---|
30 0 10 010 0 0 100 10 0 0 | 50.000 |
Kiểm tra: nhập
12-2136 -7636 -1174 -79054728 -4932 5448 -4240-1797 -1982 -1058 -2653-1981 2653 -2783 20554961 -2809 5452 -19393734 3338 3067 4083-4266 -2085 -3828 -29833360 2676 2736 3458-945 -6402 43 -65481627 3656 713 4062-1951 -752 -1593 -16854607 6680 3783 7247Nhóm 4. Góc cực và vận dụng
Phần tiêu đề “Nhóm 4. Góc cực và vận dụng”Bài 16. Tam giác chứa gốc tọa độ
Phần tiêu đề “Bài 16. Tam giác chứa gốc tọa độ”Dòng đầu là n (3 ≤ n ≤ 2000), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 109), không điểm nào trùng gốc O và không có hai điểm nào cùng nằm trên một đường thẳng qua O. In ra số tam giác có ba đỉnh là ba điểm đã cho và chứa O ở bên trong.
Ví dụ:
| Nhập | In ra |
|---|---|
42 1-1 3-3 -11 -2 | 2 |
Kiểm tra: nhập
105 11-1 13-10 -9-3 513 -2-14 1313 -419 -2-9 98 -2Bài 17. Khi nào bao được gốc tọa độ
Phần tiêu đề “Bài 17. Khi nào bao được gốc tọa độ”Dòng đầu là n (1 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm theo thứ tự xuất hiện (|x|, |y| ≤ 109). Tìm k nhỏ nhất sao cho bao lồi của k điểm đầu tiên chứa gốc O ở bên trong (không tính trên biên). In ra k, hoặc -1 nếu không có.
Ví dụ:
| Nhập | In ra |
|---|---|
51 12 3-1 10 -25 5 | 4 |
Kiểm tra: nhập
126 -39 79 36 53 77 88 1-8 -98 47 810 47 3Bài 18. Điểm nguyên trên biên bao lồi
Phần tiêu đề “Bài 18. Điểm nguyên trên biên bao lồi”Dòng đầu là n (3 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 108, không phải tất cả thẳng hàng). In ra số điểm có tọa độ nguyên nằm trên biên bao lồi của các điểm đã cho.
Ví dụ:
| Nhập | In ra |
|---|---|
50 04 04 30 32 1 | 14 |
Kiểm tra: nhập
10-9 8-4 -12-3 0-10 85 7-1 -6-3 6-7 -12-7 -6-3 1Bài 19. Điểm nguyên bên trong bao lồi
Phần tiêu đề “Bài 19. Điểm nguyên bên trong bao lồi”Dòng đầu là n (3 ≤ n ≤ 105), n dòng sau là tọa độ nguyên các điểm (|x|, |y| ≤ 108, không phải tất cả thẳng hàng). In ra số điểm có tọa độ nguyên nằm hẳn bên trong bao lồi của các điểm đã cho.
Ví dụ:
| Nhập | In ra |
|---|---|
50 04 04 30 32 1 | 6 |
Kiểm tra: nhập
104 10-9 -212 89 92 104 -18 6-9 -3-12 -43 -8Bài 20. Bỏ một cây cọc
Phần tiêu đề “Bài 20. Bỏ một cây cọc”Dòng đầu là n (4 ≤ n ≤ 1000), n dòng sau là tọa độ nguyên các cây cọc khác nhau (|x|, |y| ≤ 106). Người ta được nhổ đi đúng một cây cọc, rồi căng dây quanh các cọc còn lại. In ra hai lần diện tích nhỏ nhất có thể của vùng bên trong dây (bằng 0 nếu các cọc còn lại thẳng hàng).
Ví dụ:
| Nhập | In ra |
|---|---|
50 04 04 40 45 2 | 20 |
Kiểm tra: nhập
1017 -193 -17-15 1817 -1816 20-10 19-17 -49 -11-16 7-15 2