POJ1113 Wall

一.原题链接:

http://poj.org/problem?id=1113

二.题目大意:

给出若干个点,求一条封闭曲线能将所有点包围,并且和所有点和所有点所能连成的线段距离要小于给定长度,要求曲线长度最短,求曲线长度。

三.解题思路:

曲线的长度等价于所有点的凸包加上给定长度为半径的圆。
圆:每个多边形的角为所成的圆弧的内角,围起来再加上凸包的边。

Graham扫描法求凸包:
1. 选 x 值最小,x值相同 y 值最小的点作为基点p0
2. 按 p0p0,p0p1,p0p2...,p0pn1 极角大小升序排序。设排序后点序列为 p0,p1,...,pn
3. 维护一个栈:

  1. 先将 p0,p1,p2 入栈。
  2. 遍历排好序的点序列,从 p3 开始遍历,在每次遍历中,设从排序的点序列来的点为 p ,栈顶2个元素分别为s t t在最顶部,循环弹栈直到 st×tp>=0 遍历完栈中元素为凸包上的点。

对于点 p0,p1,p2 p0 为基点,要判断 p1,p2 排序的关系,即判断 p0p1 p0p2 的极角大小,只需要求出 p0p1×p1p2 ,大于0说明 p2 极角大。

四.代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;


class Main {
    static final int MAX_SIZE = 1050;
    static final double INF = 1e40;
    static final double ESP = 1e-4;
    static int vertexNum;
    static double length;
    static List<Point> points = new ArrayList<Point>();
    static Point base;
    static Stack<Point> s;

    static double cross(Vector v1, Vector v2){
        return v1.x*v2.y - v2.x*v1.y;
    }

    static double pointDist(Point p1, Point p2){
        return Math.sqrt((p1.x-p2.x)*(p1.x-p2.x) +
                (p1.y-p2.y)*(p1.y-p2.y));
    }

    static void sortPoints(){
        Collections.sort(points, new Comparator(){
            @Override
            public int compare(Object arg0, Object arg1) {
                Point p1 = (Point)arg0;
                Point p2 = (Point)arg1;

                Vector v1 = new Vector();
                Vector v2 = new Vector();
                v1.setXY(base, p1);
                v2.setXY(p1, p2);
                double res = cross(v1, v2); 
                if(res > 0){
                    return -1;
                }else if(res == 0){
                    return (pointDist(p1, base) > 
                    pointDist(p2, base)? 1:-1);
                }else{
                    return 1;
                }

            }

        });
    }

    static void findConvexHull(){
        s = new Stack<Point>();
        s.push(points.get(0));
        s.push(points.get(1));
        s.push(points.get(2));

        for(int i = 3; i < vertexNum; i++){
            while(true){
                Point beJudged = s.pop();

                Point begin = s.peek();
                Vector v1 = new Vector(), v2 = new Vector();
                v1.setXY(begin, beJudged);
                v2.setXY(beJudged, points.get(i));

                if(cross(v1, v2)>=0){
                    s.push(beJudged);
                    break;
                }
            }
            s.push(points.get(i));
        }

    }

    public static void main (String args[]){

        Scanner in = new Scanner(System.in);
        double x, y;

        while(in.hasNext()){
            vertexNum = in.nextInt();
            length = in.nextDouble();
            int baseIdx = 0;
            points.removeAll(points);
            for(int i = 0; i < vertexNum; i++){
                x = in.nextDouble();
                y = in.nextDouble();
                Point p = new Point();
                p.setXY(x, y);
                points.add(p);
                if(points.get(baseIdx).y > y || 
                        points.get(baseIdx).y == y && 
                        points.get(baseIdx).x > x){
                    baseIdx = i;
                }
            }

            base = points.get(baseIdx);
            sortPoints();

            findConvexHull();


            double res = pointDist(base, s.peek());

            while(s.size() > 1){
                Point p = s.pop();
                res += pointDist(p, s.peek());
            }

            Point p = s.pop();
            res += pointDist(p, base);
            res += 2*Math.PI*length;

            System.out.println(Math.round(res));
        }
        in.close();
    }
}

class Point{
    public void setXY(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double x, y;
}

class Vector{
    public void setXY(Point begin, Point end) {
        this.x = end.x-begin.x;
        this.y = end.y-begin.y;
    }

    public Vector reVector() {
        Vector v = new Vector();
        v.x = -x;
        v.y = -y;
        return v;
    }
    public double x, y;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值