zoukankan      html  css  js  c++  java
  • 半平面交

    题目: Most Distant Point from the Sea

    模板备忘。

    对于无限大的半平面,可以用一个非常大的矩形围出一块有限的面积。
    半盘面交的题目需要小心处理平行的直线。

    import java.io.*;
    import java.text.DecimalFormat;
    import java.util.*;
    
    public class Main {
    	public static void main(String[] argv) throws FileNotFoundException {
    		InputStream inS = System.in;
    		//inS = new FileInputStream("input.txt");
    		Scanner in = new Scanner(inS);
    		while (in.hasNextInt()) {
    			(new Main()).solve(in);
    		}
    	}
    	
    	final static double EPS = 1e-8;
    	
    	int n;
    	static class Vector {
    		double x, y;
    		public Vector(double a, double b) {
    			this.x = a;
    			this.y = b;
    		}
    		
    		public Vector add(Vector o) {
    			return new Vector(x + o.x, y + o.y);
    		}
    		
    		public Vector substract(Vector o) {
    			return new Vector(x - o.x, y - o.y);
    		}
    		
    		double norm() {
    			return Math.sqrt(x * x + y * y);
    		}
    		
    		Vector scalar(double len) {
    			double t = norm();
    			return new Vector(
    					x * len / t,
    					y * len / t);
    		}
    		
    		double cross(Vector o) {
    			return x * o.y - y * o.x;
    		}
    	}
    
    	private void solve(Scanner in) {
    		n = in.nextInt();
    		if (n == 0) return;
    		List<Vector> ps = new ArrayList<Vector>(n);
    		for (int i = 0; i < n; i++) {
    			ps.add(new Vector(in.nextDouble(), in.nextDouble()));
    		}
    		ps.add(ps.get(0));
    		double lo = 0.0, hi = 100000.0;
    		for (int i = 0; i < 1000; i++) {
    			double me = (lo + hi) * 0.5;
    			if (check(me, ps)) lo = me;
    			else hi = me;
    		}
    		check(lo, ps);
    		System.out.println(String.format("%.8f", lo));
    	}
    	
    	static class Segment {
    		Vector a, v;
    		Segment(Vector a2, Vector v2) {
    			a = a2;
    			v = v2;
    		}
    		public Segment shift(double shift) {
    			Vector vt = new Vector(-v.y, v.x);
    			return new Segment(a.add(vt.scalar(shift)), v);
    		}
    		
    		boolean contains(Vector p) {
    			return v.cross(p.substract(a)) >= -EPS;
    		}
    		public Vector intersect(Segment o) {
    			double ss = this.v.cross(o.v);
    			double s1 = o.v.cross(this.a.substract(o.a));
    			return a.add(new Vector(v.x * s1 / ss, v.y * s1 / ss));
    		}
    		
    		boolean parallel(Segment o) {
    			return Math.abs(this.v.cross(o.v)) < EPS;
    		}
    	}
    
    	private boolean check(double shift, List<Vector> ps) {
    		List<Segment> segs = new ArrayList<Segment>(n);
    		for (int i = 0; i < n; i++) {
    			Segment t = new Segment(ps.get(i), ps.get(i + 1).substract(ps.get(i))).shift(shift);
    			if (segs.isEmpty() || ! t.parallel((segs.get(segs.size() - 1)))) segs.add(t);
    		}
    		Deque<Segment> segq = new ArrayDeque<Segment>();
    		Deque<Vector> pq = new ArrayDeque<Vector>();
    		segq.addLast(segs.remove(0));
    		for (Segment seg : segs) {
    			while (! pq.isEmpty() && ! seg.contains(pq.getLast())) {
    				pq.removeLast();
    				segq.removeLast();
    			}
    			while (! pq.isEmpty() && ! seg.contains(pq.getFirst())) {
    				pq.removeFirst();
    				segq.removeFirst();
    			}
    			if (segq.getLast().parallel(seg)) return false;
    			pq.addLast(segq.getLast().intersect(seg));
    			segq.addLast(seg);
    		}
    		while (! pq.isEmpty() && ! segq.getFirst().contains(pq.getLast())) {
    			pq.removeLast();
    			segq.removeLast();
    		}
    		while (! pq.isEmpty() && ! segq.getLast().contains(pq.getFirst())) {
    			pq.removeFirst();
    			segq.removeFirst();
    		}
    		return pq.size() > 1;
    	}
    
    }
    
  • 相关阅读:
    计算机编程基础
    css3 压缩及验证工具
    BFC
    【原创】bootstrap框架的学习 第五课
    曼珠沙华
    仓央嘉措
    waiting for spring......
    一天
    21-chttp连接池该取多大
    守护线程会不会执行finally?默认情况new thread怎么样确定守护状态?
  • 原文地址:https://www.cnblogs.com/wangck/p/8504018.html
Copyright © 2011-2022 走看看