把坐标转(x, y)换成(x, y - x * x)之后就是求个上凸包
#include<bits/stdc++.h> #define LL long long using namespace std; const int N = (int)1e5 + 7; struct Point { LL x, y; Point(LL x = 0, LL y = 0) : x(x), y(y) {} bool operator < (const Point &rhs) const { return x < rhs.x || (x == rhs.x && y > rhs.y); } Point operator - (const Point &rhs) const { return Point(x - rhs.x, y - rhs.y); } void read() { scanf("%lld%lld", &x, &y); y = y - x * x; } }; LL det(Point A, Point B) { return A.x * B.y - A.y * B.x; } int n, m; Point a[N]; Point b[N]; int main() { scanf("%d", &n); for(int i = 0; i < n; i++) a[i].read(); sort(a, a + n); for(int i = 0; i < n; i++) { if(m == 0 || a[i].x != a[i - 1].x) a[m++] = a[i]; } n = m; m = 0; for(int i = 0; i < n; i++) { while(m >= 2 && det(b[m - 1] - b[m - 2], a[i] - b[m - 1]) >= 0) m--; b[m++] = a[i]; } printf("%d ", m - 1); return 0; } /** **/