挑战程序竞赛系列(83):3.6计算几何基础
来源:互联网 发布:js提示信息 编辑:程序博客网 时间:2024/06/01 09:46
挑战程序竞赛系列(83):3.6计算几何基础
传送门:POJ 1127: Jack Straws
之前计算几何这一块还未学习,今天开始把它们补上。
题意:
桌上放着n根木棍,木棍i的两端的坐标分别是
(pix,piy)和(qix,qiy) 。给定m对木棍(ai,bi) ,请判断每对木棍是否相连。当两根木棍之间有公共点时,就认为它们是相连的。通过相连的木棍间接的连在一起的两根木棍也认为是相连的。
思路:
因为边和边是否相连就看交点是否在线段内,可以把每条线段想象成图中的顶点,只要有交点,就认为可达,最后判断任意两条线段是否相交,只需要判断它们是否可达。
所以问题就转换成了线段与线段相交的判断。分为两种情况:
- 边平行,需要判断任何一条线段的两个顶点是否在另一条线段上。
- 非平行边,求出两条线段的交点,判断交点是否分别在这两条线段内。
求外积,其实是求三点是否能够构成三角形,如果三角形的面积为0,说明三点共线。内积判断点是否在线段内,是因为如果向量夹角超过90度,内积为负。而点在线段内,向量的夹角一定为180度。
代码如下:
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/201709/P1127.txt"; public static void main(String[] args) throws IOException { new Main().run(); } class P { static final double EPS = 1e-10; double x; double y; P(double x, double y){ this.x = x; this.y = y; } P add(P a) { return new P(add(x, a.x), add(y, a.y)); } P sub(P a) { return new P(add(x, -a.x), add(y, -a.y)); } P mul(P a) { return new P(x * a.x, y * a.y); } double dot(P a) { return add(x * a.x, y * a.y); } double det(P a) { return add(x * a.y, -y * a.x); } @Override public String toString() { return "(" + x + "," + y + ")"; } public double add(double a, double b) { if (Math.abs(a + b) < EPS * (Math.abs(a) + Math.abs(b))) return 0; return a + b; } } boolean onSeg(P p1, P p2, P q) { return p1.sub(q).det(p2.sub(q)) == 0 && p1.sub(q).dot(p2.sub(q)) <= 0; } P intersection(P p1, P p2, P q1, P q2) { double fz = q2.sub(q1).det(q1.sub(p1)); double fm = q2.sub(q1).det(p2.sub(p1)); P q = p2.sub(p1); q = new P(fz / fm * q.x, fz / fm * q.y); return p1.add(q); } void read() { while (true) { int N = ni(); if (N == 0) break; P[] p = new P[N]; P[] q = new P[N]; for (int i = 0; i < N; ++i) { p[i] = new P(nd(), nd()); q[i] = new P(nd(), nd()); } boolean[][] map = new boolean[N][N]; for (int i = 0; i < N; ++i) { map[i][i] = true; for (int j = i + 1; j < N; ++j) { if (p[i].sub(q[i]).det(p[j].sub(q[j])) == 0) { map[i][j] = map[j][i] = onSeg(p[i], q[i], p[j]) || onSeg(p[i], q[i], q[j]) || onSeg(p[j], q[j], p[i]) || onSeg(p[j], q[j], q[i]); } else { P r = intersection(p[i], q[i], p[j], q[j]); map[i][j] = map[j][i] = onSeg(p[i], q[i], r) && onSeg(p[j], q[j], r); } } } for (int k = 0; k < N; ++k) { for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { map[i][j] |= map[i][k] && map[k][j]; } } } while (true) { int a = ni(); int b = ni(); if (a + b == 0) break; a --; b --; out.println(map[a][b] ? "CONNECTED" : "NOT CONNECTED"); } } } FastScanner in; PrintWriter out; void run() throws IOException { boolean oj; try { oj = ! System.getProperty("user.dir").equals("F:\\java_workspace\\leetcode"); } 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
- 挑战程序竞赛系列(83):3.6计算几何基础
- 挑战程序竞赛系列(81):4.3 LCA(1)
- 挑战程序竞赛系列(82):4.3 LCA(2)
- 挑战程序竞赛系列(1):2.3动态规划
- 挑战程序竞赛系列(4):2.1深度优先搜索
- 挑战程序竞赛系列(5):2.1广度优先搜索
- 挑战程序竞赛系列(6):2.1穷尽搜索
- 挑战程序竞赛系列(9):2.4优先队列
- 挑战程序竞赛系列(10):2.4并查集
- 挑战程序竞赛系列(11):2.5最短路径
- 挑战程序竞赛系列(12):2.5最小生成树
- 挑战程序竞赛系列(13):2.6辗转相除法
- 挑战程序竞赛系列(14):2.6素数
- 挑战程序竞赛系列(15):2.6快速幂运算
- 挑战程序竞赛系列(16):3.1最大化最小值
- 挑战程序竞赛系列(17):3.1最大化平均值
- 挑战程序竞赛系列(20):3.2尺取法
- 挑战程序竞赛系列(21):3.2反转
- spring 如何决定使用jdk动态代理和cglib(网易面试题)
- 笔记 -- 05 -- RecyclerView与ListView比较
- unity_NGUI系统学习(三)_Button组件
- 13.go开源groupcache项目笔记——byteview_test测试代码
- 数据结构 --- Java之队列的实现
- 挑战程序竞赛系列(83):3.6计算几何基础
- 16.go开源groupcache项目笔记——部署
- SQL中常用模糊查询的四种匹配模式&&正则表达式
- hdu-1016-Prime Ring Problem
- Mysql 连接远程Linux主机无法连接 10061问题
- 《深入理解Java虚拟机》学习笔记(2)--垃圾收集器
- Activity里接收不到广播是怎么回事
- 【斜率优化】BZOJ1911(Apio2010)[特别行动队]题解
- 类和对象