【題解】AcWing 1390.通電圍欄
阿新 • • 發佈:2021-08-11
題目描述
農夫約翰的牧場可以看作是一個二維平面。
約翰為了方便看管他養的牛,構建了一個三角形的通電圍欄。
他希望他的奶牛都在圍欄圍起的區域內活動。
三角形圍欄的三個頂點位置座標分別為 (0,0),(n,m),(p,0),該圍欄由三個頂點兩兩相連而成。
平面上,所有位於三角形圍欄內部(不包括邊)且橫縱座標都為整數的點上都可以放置一頭奶牛。
請問,圍欄中最多可以放置多少頭奶牛。
輸入格式
共一行,包含三個整數 n,m,p。
輸出格式
輸出一個整數,表示可放置的牛的最大數量。
資料範圍
0≤n<32000,
0<m<32000,
0<p<32000
輸入樣例:
7 5 10
輸出樣例:
20
演算法1
(暴力?模擬) \(O(n)\)
就是把每個x的三角形三條線所對的y值算出,然後想想自己怎麼做的,就是統計y1到y2點有幾個,
這邊也沒有特別的暴力,比較完全暴力是\(O(n^2)\)時間會超,所以運用簡單的數學知識中的斜率來做就好。
這裡需要注意的主要是n與p的關係
n < p 的時候下面的線是k = 0 的線
n > p 的時候是要求的兩條線之間的點,就要相減了
還有兩點注意點
- 當這個點算出剛好是整點的情況
- double的精度誤差
C++ 程式碼
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef long long LL; int n, m, p; double k1, k2, b2; inline int get_cnt(double x) { if(p > n) { if(x < n) return (int)(k1 * x - 1e-8); return (int)(k2 * x + b2 - 1e-8); } if(x < p) return (int)(k1 * x - 1e-8); return (int)(k1 * x - 1e-8) - (int)(k2 * x + b2 + 1e-8); // l2: (- 1e-8) x } int main() { ios::sync_with_stdio(0); cin.tie(0); cin >> n >> m >> p; k1 = 1.0 * m / n, k2 = 1.0 * m / (n - p), b2 = - k2 * p; // cout << k1 << ' ' << k2 << ' ' << b2 << endl; LL res = 0; for(int i = 1; i < max(p, n); i ++) { res += get_cnt(i); // cout << get_cnt(i) << endl; } cout << res << endl; return 0; }