SW练习_POJ1113_凸包

本文详细介绍了如何解决编程竞赛题目POJ1113中的凸包问题,涉及到几何算法和数据结构的应用。通过实例解析了求解凸包的基本步骤,并给出了高效的算法实现,帮助程序员提升在几何问题上的解题能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package info.frady.poj;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class POJ1113 {
    static Point1113 a;
    public static void main(String[] args) throws Exception{
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer(reader.readLine());
        int N=Integer.parseInt(st.nextToken());
        int L=Integer.parseInt(st.nextToken());
        Point1113[] arr=new Point1113[N];
        int minIndex=0;
        for (int i = 0; i <N ; i++) {
            st=new StringTokenizer(reader.readLine());
            int x=Integer.parseInt(st.nextToken());
            int y=Integer.parseInt(st.nextToken());
            arr[i]=new Point1113(x,y);
            if(y<arr[minIndex].y ||(y==arr[minIndex].y && x<arr[minIndex].x) ){
                minIndex=i;
            }
        }
        Point1113 temp=arr[minIndex];
        arr[minIndex]=arr[0];
        arr[0]=temp;
        a=arr[0];
        Arrays.sort(arr, 1, N, new Comparator<Point1113>() {
            @Override
            public int compare(Point1113 b, Point1113 c) {
                int result=ccw(a,b,c);
                if(result>0){
                    return -1;
                }else if(result<0){
                    return 1;
                }else{
                    int d1=dis(a,b);
                    int d2=dis(a,c);
                    return d1-d2;
                }
            }
        });

        LinkedList<Point1113> list=new LinkedList<Point1113>();
        list.push(a);
        for (int i = 1; i <N ; i++) {
            Point1113 b=arr[i];
            list.push(b);
            if(i==N-1){//已经是最后一个了,最后一个点肯定是凸点,不用进行ccw了
                break;
            }

            while(ccw(list.get(1),list.peek(),arr[i+1])<=0){
                list.pop();
                if(list.size()<=2){
                    break;
                }
            }
        }
        double sum=0;
        list.push(a);
        for (int i = 0; i <list.size()-1 ; i++) {
            Point1113 p1=list.get(i);
            Point1113 p2=list.get(i+1);
            sum=sum+Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
        }
        sum+=2*L*Math.PI;
        System.out.println(Math.round(sum));


        reader.close();
    }

    public static int dis(Point1113 a,Point1113 b){
        return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }

    public static int ccw(Point1113 a,Point1113 b,Point1113 c){
        return (a.x*b.y+b.x*c.y+c.x*a.y)-(a.y*b.x+b.y*c.x+c.y*a.x);
    }


    static class Point1113{
        public Point1113(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int x;
        public int y;

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值