[kuangbin] 專題13 基礎計算幾何 題解 + 總結
阿新 • • 發佈:2020-10-20
kuangbin帶你飛
:點選進入新世界
[kuangbin]
專題7 線段樹 題解 + 總結:https://www.cnblogs.com/RioTian/p/13413897.html
kuangbin
專題十二 基礎DP1 題解+總結:https://www.cnblogs.com/RioTian/p/13110438.html
kuangbin
專題六 最小生成樹 題解+總結:https://www.cnblogs.com/RioTian/p/13380764.html
[kuangbin]
專題九 連通圖 題解+總結 : https://www.cnblogs.com/RioTian/p/13395039.html
計算幾何分類blog: https://www.cnblogs.com/RioTian/category/1852545.html
總結
1、TOYS POJ - 2318
題目連結: Click Here
題目大意: 有一個方盒子 有N個板隔開 分成N+1個區域
又給了M個玩具的座標 問你每個區域內(不能恰好在區域內)的玩具有幾個(忽略玩具體積)
解題思路: 每相鄰的兩個板看成兩個向量 分別求其與其中一點和玩具座標的叉積 如果兩叉積的乘積<0 就說明這個玩具座標點在一個板的右邊 一個板的左邊
因為資料量比較大 可以把板和方盒的兩邊記錄下來 然後二分 道理是一樣的
AC程式碼:
// Author : RioTian // Time : 20/10/20 #include <algorithm> #include <cmath> #include <cstdlib> #include <cstring> #include <iostream> #define ms(a, b) memset(a, b, sizeof a) using namespace std; typedef long long ll; const int N = 5000 + 10; int num[N], x[N], y[N]; struct node { double x, y; } pu[N], pl[N], q; int n, m, f; int mul(node p1, node p2, node p3) { return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y); } void Bisearch(node x) { int l = 0, r = n + 1, ans; while (l <= r) { int mid = (l + r) >> 1; if (mul(x, pu[mid], pl[mid]) < 0) ans = mid, r = mid - 1; else l = mid + 1; } num[ans - 1]++; } int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int x1, x2, y1, y2; while (cin >> n) { if (n == 0) break; ms(num, 0); cin >> m >> x1 >> y1 >> x2 >> y2; // scanf("%d %d %d %d %d", &m, &x1, &y1, &x2, &y2); pu[0].x = x1, pu[0].y = y1; pl[0].x = x1, pl[0].y = y2; for (int i = 1; i <= n; ++i) { // scanf("%d %d", &pu[i].x, &pl[i].x); cin >> pu[i].x >> pl[i].x; pu[i].y = y1, pl[i].y = y2; } pu[n + 1].x = x2, pu[n + 1].y = y1; pl[n + 1].x = x2, pl[n + 1].y = y2; for (int i = 0; i < m; i++) { // scanf("%d %d", &q.x, &q.y); cin >> q.x >> q.y; Bisearch(q); } if (f == 1) printf("\n"); f = 1; for (int i = 0; i <= n; i++) printf("%d: %d\n", i, num[i]); } }
2、Toy Storage POJ - 2398
題目連結:Click Here