Codeforces 1142C(转化、凸包)

可以变换坐标: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 }
原文地址:https://www.cnblogs.com/AlphaWA/p/10660648.html