POJ 1379 Run Away

来源:互联网 发布:好评100被淘宝拦截订单 编辑:程序博客网 时间:2024/05/29 03:20
/*ID: daniel.20LANG: JAVATASK: starry*/import java.util.*;import java.io.*;class node{    double x,y;    public node(double a,double b){        x=a;y=b;    }}class problem2{    StringBuilder sb = new StringBuilder();    long start = System.currentTimeMillis();    double PI = Math.acos(-1.0);    double eps = 1e-9;    int x_size, y_size, m;    node[] arr;    int P = 30, L=30;    node seed[];    double best[];    int idx; double result;    int[][] graph;    void solver() throws IOException{          //BufferedReader reader = new BufferedReader(new FileReader("starry.in"));        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));        int cases = Integer.valueOf(reader.readLine());        while(cases-->0){            StringTokenizer st = new StringTokenizer(reader.readLine());            x_size = Integer.parseInt(st.nextToken());            y_size = Integer.parseInt(st.nextToken());            m = Integer.parseInt(st.nextToken());            arr = new node[m];            seed = new node[P];            best = new double[P];            result = 0;            graph = new int[x_size+1][y_size+1];            for(int i=0;i<m;i++){                st = new StringTokenizer(reader.readLine());                double t1 = Double.parseDouble(st.nextToken());                double t2 = Double.parseDouble(st.nextToken());                arr[i] = new node(t1,t2);            }            for(int i=0;i<P;i++){                double t1 = (Math.random()%1000+1/1000.0)*x_size;                double t2 = (Math.random()%1000+1/1000.0)*y_size;                seed[i] = new node(t1,t2);                best[i] = min_dist(seed[i]);            }            double step = Math.max(x_size, y_size)/Math.sqrt(1.0*m);            while(step>1e-3){                for(int i=0;i<P;i++){                    for(int j=0;j<L;j++){                        double angle = (Math.random()%1000+1/1000.0)*2*PI;                        double nx = seed[i].x+Math.cos(angle)*step;                        double ny = seed[i].y+Math.sin(angle)*step;                        node next = new node(nx,ny);                        if(!is_legal(next)) continue;                        double tmp = min_dist(next);                        if(tmp-best[i]>eps){                            best[i] = tmp;                            seed[i] = next;                        }                        if(best[i]-result>eps){                            result = best[i];                            idx = i;                        }                    }                }                step*=0.85;            }            System.out.printf("The safest point is (%.1f, %.1f).\n",seed[idx].x,seed[idx].y);        }        System.exit(0);            }    double dist(node a, node b){        return Math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));    }    double min_dist(node a){        double gagaga = Double.MAX_VALUE;        for(int i=0;i<arr.length;i++){            gagaga = Math.min(gagaga,dist(arr[i],a));        }        return gagaga;    }    boolean is_legal(node a){        if(a.x-x_size>eps||a.x<-eps||a.y<-eps||a.y-y_size>eps) return false;        return true;    }}public class starry {    public static void main(String[] args) throws Exception {        problem2 p = new problem2();        p.solver();    }}

求一个平面上到所有已知点距离中大的

模拟退火,神算法。。。理解的不是很好

基本上来说,就是在平面上随机出几个点,这里取了P=30

然后每个点对于半径为step长的圆,取一个随机角度生成下一个点

这里随机了30个角度。。。

总的说就是随机出各种点,但是这个参数step怎么出来的,还有0.85尼玛怎么随出来的,完全不会。。。

不太能理解随机算法如何证明能得到正确解。。。计算几何果然恐怖


0 0
原创粉丝点击