您的位置:首页 > Web前端

usaco 5.2.2 Electric Fences

2014-06-28 14:19 351 查看
/*
ID: daniel.20
LANG: JAVA
TASK: 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找小数位
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: