usaco 5.2.2 Electric Fences

来源:互联网 发布:淘宝客服处理售后问题 编辑:程序博客网 时间:2024/06/05 14:10
/*ID: daniel.20LANG: JAVATASK: fence3*/import java.util.*;import java.io.*;class node{    double x,y;    public node(double a,double b){        x=a;y=b;    }}class line{    node node1, node2;    public line(double t1, double t2, double t3, double t4){        this.node1=new node(t1,t2);        this.node2=new node(t3,t4);    }}class problem2{    StringBuilder sb = new StringBuilder();    long start = System.currentTimeMillis();    double PI = Math.acos(-1.0);    double eps = 1e-9;    double x_size, y_size; int f;    line[] arr;    int P = 30, L=30;    node seed[];    double best[];    int idx; double result;        void solver() throws IOException{          BufferedReader reader = new BufferedReader(new FileReader("fence3.in"));        //BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));        StringTokenizer st = new StringTokenizer(reader.readLine());        f = Integer.parseInt(st.nextToken());        arr = new line[f];        seed = new node[P];        best = new double[P];        result = Double.MAX_VALUE;        x_size=-1;y_size=-1;        for(int i=0;i<f;i++){            st = new StringTokenizer(reader.readLine());            double t1 = Double.parseDouble(st.nextToken());            if(t1>x_size) x_size=t1;            double t2 = Double.parseDouble(st.nextToken());            if(t2>y_size) y_size=t2;            double t3 = Double.parseDouble(st.nextToken());            if(t3>x_size) x_size=t3;            double t4 = Double.parseDouble(st.nextToken());                        if(t4>y_size) y_size=t4;            arr[i] = new line(t1,t2,t3,t4);        }        for(int i=0;i<P;i++){           double t1 = (Math.random()%100+1/100.0)*x_size;           double t2 = (Math.random()%100+1/100.0)*y_size;           seed[i] = new node(t1,t2);           best[i] = sum_dist(seed[i]);        }        double step = Math.max(x_size, y_size)/Math.sqrt(1.0*f);        while(step>1e-3){            for(int i=0;i<P;i++){                for(int j=0;j<L;j++){                    double angle = (Math.random()%100+1/100.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 = sum_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("%.1f %.1f %.1f\n",seed[idx].x,seed[idx].y, result);        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("fence3.out")));        out.printf("%.1f %.1f %.1f\n",seed[idx].x,seed[idx].y, result);        out.close();        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 point_line_dist(node line1, node line2, node p){        double a = dist(line1,p);        if(a<eps) return 0.0;        double b = dist(line2,p);        if(b<eps) return 0.0;        double c = dist(line1, line2);        if(c<eps) return a;        if(a*a>=b*b+c*c) return b;        if(b*b>=a*a+c*c) return a;        double tmp = (a+b+c)/2;        double s= Math.sqrt(tmp*(tmp-a)*(tmp-b)*(tmp-c));        return 2*s/c;    }    double sum_dist(node a){        double gagaga = 0;        for(int i=0;i<f;i++)             gagaga+=point_line_dist(arr[i].node1, arr[i].node2, 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 fence3 {    public static void main(String[] args) throws Exception {        problem2 p = new problem2();        p.solver();    }}

模拟退火挺好玩哈。。。

拿之前的代码来乱搞了一下就1A了 哈哈哈

这个题目也是精度为1,并且数据范围更小,才0到100的坐标


其实暴力也行,1000×1000个点或者先找100个整数点中最好的,然后再10×10找小数位

0 0