「HDOJ1007」平面最近点对 分治

import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader sc = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(1, sc, out);
        out.close();
    }

    static class Task {
        public double[][] p;

        public double calc(double[] p1,double[] p2){
            return Math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1]));
        }

        public double dfs(Integer[] x,Integer[] y){
            if(x.length<=3){
                double ans=Double.MAX_VALUE;
                for(int i=0;i<x.length;i++){
                    for(int j=i+1;j<x.length;j++){
                        ans=Math.min(ans,calc(p[x[i]],p[x[j]]));
                    }
                }
                return ans;
            }
            int n=x.length;
            Integer[] xl=new Integer[n/2];
            Integer[] xr=new Integer[n-n/2];
            Integer[] yl=new Integer[n/2];
            Integer[] yr=new Integer[n-n/2];
            for(int i=0;i<n;i++){
                if(i<n/2)
                    xl[i]=x[i];
                else
                    xr[i-n/2]=x[i];
            }
            HashSet<Integer> leftSet=new HashSet<>();
            for(int v:xl)
                leftSet.add(v);
            int lidx=0;
            int ridx=0;
            for(int v:y){
                if(leftSet.contains(v))
                    yl[lidx++]=v;
                else
                    yr[ridx++]=v;
            }
            double ans=Math.min(dfs(xl,yl),dfs(xr,yr));
            double nowx=p[x[n/2]][0];
            ArrayList<Integer> tempy=new ArrayList<>();
            for(int i=0;i<n;i++){
                if(p[y[i]][0]<nowx-ans||p[y[i]][0]>nowx+ans)
                    continue;
                tempy.add(y[i]);
            }
            for(int i=0;i< tempy.size();i++){
                for(int j=i+1;j<Math.min(tempy.size(),i+8);j++){
                    if(p[tempy.get(j)][1]-p[tempy.get(i)][1]>ans)
                        break;
                    ans=Math.min(ans,calc(p[tempy.get(i)],p[tempy.get(j)]));
                }
            }
            return ans;
        }

        public void solve(int testNumber, InputReader sc, PrintWriter out) throws IOException {
            int n=sc.nextInt();
            while(n!=0){
                p=new double[n][2];
                for(int i=0;i<n;i++){
                    p[i][0]=sc.nextDouble();
                    p[i][1]=sc.nextDouble();
                }
                Integer[] idx=new Integer[n];
                Integer[] idy=new Integer[n];
                for(int i=0;i<n;i++)
                    idx[i]=idy[i]=i;
                Arrays.sort(idx, new Comparator<Integer>() {
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        if(p[o1][0]>p[o2][0])
                            return 1;
                        if(p[o1][0]<p[o2][0])
                            return -1;
                        return 0;
                    }
                });
                Arrays.sort(idy,new Comparator<Integer>() {
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        if(p[o1][1]>p[o2][1])
                            return 1;
                        if(p[o1][1]<p[o2][1])
                            return -1;
                        return 0;
                    }
                });
                double ans=dfs(idx,idy);
                out.println(String.format("%.2f",ans/2));
                n=sc.nextInt();
            }
        }
    }

    static class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }

        public double nextDouble() throws NumberFormatException, IOException {
            return Double.parseDouble(next());
        }

        public BigInteger nextBigInteger() throws IOException {
            return new BigInteger(next());
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值