2018 ICPC Asia Singapore Regional A. Largest Triangle (计算几何)

题目链接:Kattis - largesttriangle

Description

Given \(N\) points on a \(2\)-dimensional space, determine the area of the largest triangle that can be formed using \(3\) of those \(N\) points. If there is no triangle that can be formed, the answer is \(0\).

Input

The first line contains an integer \(N (3≤N≤5000)\) denoting the number of points. Each of the next \(N\) lines contains two integers \(x\) and \(y (0≤x,y≤4?10^7)\). There are no specific constraints on these \(N\) points, i.e. the points are not necessarily distinct, the points are not given in specific order, there may be \(3\) or more collinear points, etc.

Output

Print the answer in one line. Your answer should have an absolute error of at most \(10^{?5}\).

Sample Input

7
0 0
0 5
7 7
0 10
0 0
20 0
10 10

Sample Output

100.00000

Source

2018 ICPC Asia Singapore Regional

Solution

题意

给出 \(N\) 个点,选择其中 \(3\) 个点组成三角形,求最大面积的三角形的面积,如果不能组成三角形,输出 \(0\)。

题解

最大面积的三角形一定在凸包上,所以先求凸包。

接下来在凸包上枚举三个点。直接三重循环肯定超时。

可以枚举凸包上的两个点,另外一个点根据面积的单调性枚举。时间复杂度 \(O(N^2)\)。

还有 \(O(NlogN)\) 的做法,可以参考这篇论文

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const db eps = 1e-10;
const db pi = acos(-1.0);
const ll maxn = 5010;

inline int dcmp(db x) {
    if(fabs(x) < eps) return 0;
    return x > 0? 1: -1;
}

class Point {
public:
    double x, y;
    Point(double x = 0, double y = 0) : x(x), y(y) {}

    void input() {
        scanf("%lf%lf", &x, &y);
    }

    bool operator<(const Point &a) const {
        return (!dcmp(x - a.x))? dcmp(y - a.y) < 0: x < a.x;
    }

    bool operator==(const Point &a) const {
        return dcmp(x - a.x) == 0 && dcmp(y - a.y) == 0;
    }

    db dis2(const Point a) {
        return pow(x - a.x, 2) + pow(y - a.y, 2);
    }

    db dis(const Point a) {
        return sqrt(dis2(a));
    }

    db dis2() {
        return x * x + y * y;
    }

    db dis() {
        return sqrt(dis2());
    }

    Point operator+(const Point a) {
        return Point(x + a.x, y + a.y);
    }

    Point operator-(const Point a) {
        return Point(x - a.x, y - a.y);
    }

    Point operator*(double p) {
        return Point(x * p, y * p);
    }

    Point operator/(double p) {
        return Point(x / p, y / p);
    }

    db dot(const Point a) {
        return x * a.x + y * a.y;
    }

    db cross(const Point a) {
        return x * a.y - y * a.x;
    }
};

db area(Point A, Point B, Point C) {
    return abs((A - B).cross(A - C));
}

typedef vector<Point> Polygon;
Polygon Andrew(vector<Point> p) {
    int n = p.size(), cnt = 0;
    Polygon ans(2 * n);
    sort(p.begin(), p.end());
    for (int i = 0; i < n; ++i) {
        while (cnt >= 2 && (ans[cnt - 1] - ans[cnt - 2]).cross(p[i] - ans[cnt - 2]) < eps) {
            --cnt;
        }
        ans[cnt++] = p[i];
    }
    int t = cnt + 1;
    for (int i = n - 1; i > 0; --i) {
        while (cnt >= t && (ans[cnt - 1] - ans[cnt - 2]).cross(p[i - 1] - ans[cnt - 2]) < eps) {
            --cnt;
        }
        ans[cnt++] = p[i - 1];
    }
    ans.resize(cnt - 1);
    return ans;
}

vector<Point> p;

int main() {
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) {
        Point tmp;
        tmp.input();
        p.push_back(tmp);
    }
    p = Andrew(p);
    n = p.size();
    db ans = 0.0;
    if(n < 3) {
        printf("%.5lf\n", ans);
        return 0;
    }
    for(int i = 0; i < n; ++i) {
        int k = i + 2;
        for(int j = i + 1; j < n; ++j) {
            while(k + 1 < n && area(p[i], p[j], p[k]) < area(p[i], p[j], p[k + 1])) {
                ++k;
            }
            ans = max(ans, area(p[i], p[j], p[k]));
        }
    }
    printf("%.5lf\n", ans * 0.5);
    return 0;
}

原文地址:https://www.cnblogs.com/wulitaotao/p/11626009.html

时间: 2024-08-29 08:51:20

2018 ICPC Asia Singapore Regional A. Largest Triangle (计算几何)的相关文章

2018 ICPC Asia Jakarta Regional Contest

题目传送门 题号 A B C D E F G H I J K L 状态 Ο . . Ο . . . . Ο . . Ο Ο:当场 Ø:已补 .  :  待补 A. Edit Distance Thinking:kk pai爷 Code:kk 不能直接反转,比如"010101",直接反转后就变成"101010",右移一位,然后加个0就可以了. 所以要先统计01的数量,如果0大于1,就全变成1,1大于0,就全变成0(从数量上的改变就大于s/2了),相等的话,就看首位是0

2018-2019, ICPC, Asia Yokohama Regional Contest 2018 (Gym - 102082)

2018-2019, ICPC, Asia Yokohama Regional Contest 2018 A - Digits Are Not Just Characters 签到. B - Arithmetic Progressions 题意:从给定的集合中选出最多的数构成等差数列. 题解:数字排序后,设\(dp[i][j]\)表示等差数列最后一个数字为\(a[i]\),倒数第二个数字为\(a[j]\)的最大个数.然后对于每一位枚举 \(i\),\(lower\_bound()\)找有无合法的

2019-2020 ICPC, Asia Jakarta Regional Contest H. Twin Buildings

As you might already know, space has always been a problem in ICPC Jakarta. To cope with this, ICPC Jakarta is planning to build two new buildings. These buildings should have a shape of a rectangle of the same size. Now, their problem is to find lan

2019 ICPC Asia Yinchuan Regional

目录 Contest Info Solutions A. Girls Band Party B. So Easy D. Easy Problem E. XOR Tree F. Function! G. Pot!! H. Delivery Route I. Base62 K. Largest Common Submatrix N. Fibonacci Sequence Contest Info Practice Link Solved A B C D E F G H I J K L M N 9/1

The 2018 ACM-ICPC Asia Qingdao Regional Contest K XOR Clique

K XOR Clique BaoBao has a sequence a?1??,a?2??,...,a?n??. He would like to find a subset S of {1,2,...,n} such that ?i,j∈S, a?i??⊕a?j??<min(a?i??,a?j??) and ∣S∣ is maximum, where ⊕ means bitwise exclusive or. Input There are multiple test cases. The

The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online - H Traveling on the Axis-【思维模拟题目】

H Traveling on the Axis 作者: 浙江大学竞赛命题组 单位: ACMICPC 时间限制: 500 ms 内存限制: 64 MB 代码长度限制: 32 KB 传送门 BaoBao is taking a walk in the interval [0,n] on the number axis, but he is not free to move, as at every point (i−0.5) for all i∈[1,n], where i is an intege

ZOJ 4063 - Tournament - [递归][2018 ACM-ICPC Asia Qingdao Regional Problem F]

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4063 Input Output Sample Input 2 3 1 4 3 Sample Output Impossible 2 1 4 3 3 4 1 2 4 3 2 1 题意: 说现在有 $n$ 个人打比赛,要你安排 $k$ 轮比赛,要求每轮每个人都参加一场比赛. 所有轮次合起来,任意一对人最多比赛一场. 且对于任意的第 $i,j$ 轮,若 $a,b$ 在

ZOJ 4062 - Plants vs. Zombies - [二分+贪心][2018 ACM-ICPC Asia Qingdao Regional Problem E]

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4062 题意: 现在在一条 $x$ 轴上玩植物大战僵尸,有 $n$ 个植物,编号为 $1 \sim n$,第 $i$ 个植物的位置在坐标 $i$,成长值为 $a_i$,初始防御值为 $d_i$. 现在有一辆小车从坐标 $0$ 出发,每次浇水操作必须是先走 $1$ 单位长度,然后再进行浇水,植物被浇一次水,防御值 $d_i+=a_i$. 现在知道,小车最多进行 $m

2018 ACM-ICPC, Asia Shenyang Regional Contest CEJ

C. Insertion Sort 求有多少 1 到 n 的排列 满足条件将前 k 个的数排列以后 最长上升子序列长度为 n?1 以上 队友推了式子 试了下就过了 1 #include<bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 5 ll ans,n,k,p; 6 7 ll PP() 8 { 9 ll sum=1; 10 for(int i=1;i<=k;i++) 11 sum=(sum*i)%p; 12