可以变换坐标:x' = x, y' = y - x ^ 2,如此之后可得线性函数x' * b + c = y',可以发现两点连边为抛物线,而其他点都在这条线下方才满足题意,故而求一个上凸壳即可。
1 #include <cstdio> 2 #include <cmath> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 8 typedef long long ll; 9 const int maxn = 1e5 + 5; 10 int n; 11 struct Point { 12 ll x, y; 13 14 Point(){} 15 Point(ll x, ll y):x(x), y(y) {} 16 17 friend ll operator * (const Point &a, const Point &b) { 18 return a.y * b.x - b.y * a.x; 19 } 20 21 friend Point operator - (const Point &a, const Point &b) { 22 return Point(a.x - b.x, a.y - b.y); 23 } 24 25 bool operator < (const Point &rhs) const { 26 if (x != rhs.x) return x < rhs.x; 27 return y < rhs.y; 28 } 29 }; 30 31 vector<Point> v, st; 32 33 void read() { 34 cin >> n; 35 36 for (int i = 0; i < n; i++) { 37 ll x, y; 38 cin >> x >> y; 39 y = y - x * x; 40 v.push_back({x, y}); 41 } 42 } 43 44 void convex() { 45 sort(v.begin(), v.end());//按坐标排序 46 47 for (int i = n - 1; ~i; --i) 48 v[i] = v[i] - v[0]; 49 50 for (int i = 0; i < n; i++) { 51 int tot = st.size(); 52 while (tot > 1 && (v[i] - st[tot - 2]) * (st[tot - 1] - st[tot - 2]) >= 0) tot--, st.pop_back(); 53 st.push_back(v[i]); 54 } 55 } 56 57 int main() { 58 ios_base::sync_with_stdio(0); 59 cin.tie(0), cout.tie(0); 60 61 read(); 62 convex(); 63 64 int ans = 0; 65 for (int i = 1; i < st.size(); i++) 66 if (st[i].x != st[i - 1].x)//x相同无法构成二次函数 67 ans++; 68 cout << ans << endl; 69 70 return 0; 71 }