挑战程序竞赛系列(94):3.6凸包(5)
来源:互联网 发布:js 拖动事件 编辑:程序博客网 时间:2024/09/21 06:22
挑战程序竞赛系列(94):3.6凸包(5)
传送门:POJ 2079: Triangle
题意:
求三个点构成的最大三角形面积。
思路:
可以证明,三点构成的最大三角形面积一定在凸包上,传统算法for循环三次,时间复杂度为
性质1:
因为凸包上满足性质:循环遍历R时,三角形面积先增后减,找到最大即可停止搜索。
性质2:
利用(P, Q)求得的点R,在搜索(Q, Q_next)的最大三角形面积时,可以从点R开始继续向后搜索,而不需要从头开始。
综上,时间复杂度降为
代码如下:
import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.util.Arrays;import java.util.Map;import java.util.StringTokenizer;public class Main{ String INPUT = "./data/judge/201710/P2079.txt"; public static void main(String[] args) throws IOException { new Main().run(); } class P implements Comparable<P>{ int x; int y; P(int x, int y){ this.x = x; this.y = y; } P sub(P a) { return new P(x - a.x, y - a.y); } int det(P a) { return x * a.y - y * a.x; } @Override public int compareTo(P o) { return x - o.x != 0 ? x - o.x : y - o.y; } } int N; P[] p; double area(P a, P b, P c) { double ans = (c.x - a.x) * (b.y - a.y) - (c.y - a.y) * (b.x - a.x); return 0.5 * Math.abs(ans); } P[] convexHull() { Arrays.sort(p); P[] qs = new P[2 * N]; int k = 0; for (int i = 0; i < N; ++i) { while (k > 1 && qs[k - 1].sub(qs[k - 2]).det(p[i].sub(qs[k - 2])) < 0) k --; qs[k++] = p[i]; } for (int i = N - 2, t = k; i >= 0; --i) { while (k > t && qs[k - 1].sub(qs[k - 2]).det(p[i].sub(qs[k - 2])) < 0) k--; qs[k++] = p[i]; } P[] res = new P[k - 1]; System.arraycopy(qs, 0, res, 0, k - 1); return res; } void solve() { P[] qs = convexHull(); int n = qs.length; double ans = 0; for (int offset = 1; offset < (n + 1) / 2; ++offset) { int fir = 0; int pos = (fir + offset + 1) % n; do { int sec = (fir + offset) % n; while ((pos + 1) % n != fir && area(qs[fir % n], qs[sec % n], qs[(pos + 1) % n]) >= area(qs[fir % n], qs[sec % n], qs[pos % n])) { pos = (pos + 1) % n; } ans = Math.max(ans, area(qs[fir % n], qs[sec % n], qs[pos % n])); fir = (fir + 1) % n; } while (fir != 0); } out.printf("%.2f\n", ans); } void read() { while (true) { N = ni(); if (N == -1) break; p = new P[N]; for (int i = 0; i < N; ++i) { p[i] = new P(ni(), ni()); } solve(); } } FastScanner in; PrintWriter out; void run() throws IOException { boolean oj; try { oj = ! System.getProperty("user.dir").equals("F:\\oxygen_workspace\\Algorithm"); } catch (Exception e) { oj = System.getProperty("ONLINE_JUDGE") != null; } InputStream is = oj ? System.in : new FileInputStream(new File(INPUT)); in = new FastScanner(is); out = new PrintWriter(System.out); long s = System.currentTimeMillis(); read(); out.flush(); if (!oj){ System.out.println("[" + (System.currentTimeMillis() - s) + "ms]"); } } public boolean more(){ return in.hasNext(); } public int ni(){ return in.nextInt(); } public long nl(){ return in.nextLong(); } public double nd(){ return in.nextDouble(); } public String ns(){ return in.nextString(); } public char nc(){ return in.nextChar(); } class FastScanner { BufferedReader br; StringTokenizer st; boolean hasNext; public FastScanner(InputStream is) throws IOException { br = new BufferedReader(new InputStreamReader(is)); hasNext = true; } public String nextToken() { while (st == null || !st.hasMoreTokens()) { try { st = new StringTokenizer(br.readLine()); } catch (Exception e) { hasNext = false; return "##"; } } return st.nextToken(); } String next = null; public boolean hasNext(){ next = nextToken(); return hasNext; } public int nextInt() { if (next == null){ hasNext(); } String more = next; next = null; return Integer.parseInt(more); } public long nextLong() { if (next == null){ hasNext(); } String more = next; next = null; return Long.parseLong(more); } public double nextDouble() { if (next == null){ hasNext(); } String more = next; next = null; return Double.parseDouble(more); } public String nextString(){ if (next == null){ hasNext(); } String more = next; next = null; return more; } public char nextChar(){ if (next == null){ hasNext(); } String more = next; next = null; return more.charAt(0); } }}
阅读全文
0 0
- 挑战程序竞赛系列(94):3.6凸包(5)
- 挑战程序竞赛系列(90):3.6凸包(1)
- 挑战程序竞赛系列(91):3.6凸包(2)
- 挑战程序竞赛系列(92):3.6凸包(3)
- 挑战程序竞赛系列(93):3.6凸包(4)
- 挑战程序竞赛系列(83):3.6计算几何基础
- 挑战程序竞赛系列(5):2.1广度优先搜索
- 挑战程序竞赛系列(81):4.3 LCA(1)
- 挑战程序竞赛系列(82):4.3 LCA(2)
- 挑战程序竞赛系列(1):2.3动态规划
- 挑战程序竞赛系列(4):2.1深度优先搜索
- 挑战程序竞赛系列(6):2.1穷尽搜索
- 挑战程序竞赛系列(9):2.4优先队列
- 挑战程序竞赛系列(10):2.4并查集
- 挑战程序竞赛系列(11):2.5最短路径
- 挑战程序竞赛系列(12):2.5最小生成树
- 挑战程序竞赛系列(13):2.6辗转相除法
- 挑战程序竞赛系列(14):2.6素数
- BZOJ 4726 Sabota? (树型dp)
- sdnu1042购物
- Java基准测试 JMH
- 初识react native 练习记录
- Tensorflow 查看变量的值
- 挑战程序竞赛系列(94):3.6凸包(5)
- 数据挖掘一般过程总结
- 在Ubuntu/Windows下配置Synergy-键盘鼠标共享
- MyBatis的4种引入映射器的方法,及报错解决方案
- 今日头条实习生面试
- java获取文件的md5值
- 【深度分析】Java的枚举类型
- 基于DragonBoard410C的智能管家
- 论坛方法