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找小数位
相关文章推荐
- [USACO5.2.2 Electric Fences]
- usaco traini 5.2.2 Electric Fences 题解
- USACO 5.2.2
- USACO6.4.2 Electric Fences(fence3)
- USACO Section 5.2 Electric Fences - 有意思的枚举+计算几何
- USACO6.4-Electric Fences:计算几何
- [USACO 6.4.2] Electric Fences
- USACO 6.4 Electric Fences
- usaco6.4.2 Electric Fences
- [USACO3.4.3 Electric Fences]
- USACO 6.4.2 Electric Fences 三分算法
- USACO 5.2.2 fence3
- Electric Fences[USACO]
- USACO 5.2 Electric Fences(模拟退火)
- Electric Fences_usaco3.4_皮克定理
- usaco 5.2 Electric Fences(模拟退火)
- USACO 3.2 butter 最短路
- 【C++】【USACO1.1.1】飞碟在这儿
- [USACO 2014 Jan Silver]ccski
- USACO 5.1 Musical Themes(哈希+二分)