4 public class asteroids_rs
implements Runnable
{
5 private BufferedReader in
;
6 private PrintWriter out
;
8 private void check(boolean expr
, String msg
) {
14 private void checkBounds(int n
, int low
, int hi
, String nStr
) {
15 check((low
<= n
) && (n
<= hi
), nStr
+ " is not in [" + low
+ ", " + hi
+ "]");
18 private class Polyhedron
{
19 private int[] x
, y
, z
;
21 private List
<List
<Integer
>> facets
;
22 private long vpa
, vpb
, vpc
, vpd
;
23 private double xc
, yc
, zc
;
24 private double minDist
;
26 private void vectorProduct(int i
, int j
, int k
) {
27 int dx1
= x
[j
] - x
[i
];
28 int dy1
= y
[j
] - y
[i
];
29 int dz1
= z
[j
] - z
[i
];
30 int dx2
= x
[k
] - x
[i
];
31 int dy2
= y
[k
] - y
[i
];
32 int dz2
= z
[k
] - z
[i
];
33 vpa
= dy1
* dz2
- dy2
* dz1
;
34 vpb
= -(dx1
* dz2
- dx2
* dz1
);
35 vpc
= dx1
* dy2
- dx2
* dy1
;
36 vpd
= -vpa
* x
[i
] - vpb
* y
[i
] - vpc
* z
[i
];
39 private void checkConvexFacet(long a
, long b
, long c
, long d
, List
<Integer
> facet
) {
41 int num1
= facet
.get(0);
42 for (int i
= 1; i
< m
; i
++) {
43 for (int j
= 1; j
+ 1 < m
; j
++) {
44 int num2
= facet
.get(j
);
45 int num3
= facet
.get(j
+ 1);
46 vectorProduct(num1
, num2
, num3
);
47 long sp
= a
* vpa
+ b
* vpb
+ c
* vpc
;
48 check(sp
!= 0, "Three points on a line");
51 facet
.set(j
+ 1, num2
);
55 for (int i
= 0; i
< m
; i
++) {
56 for (int j
= i
+ 1; j
< m
; j
++) {
57 for (int k
= j
+ 1; k
< m
; k
++) {
58 vectorProduct(facet
.get(i
), facet
.get(j
), facet
.get(k
));
59 long sp
= a
* vpa
+ b
* vpb
+ c
* vpc
;
60 check(sp
> 0, "Facet not convex");
66 public Polyhedron() throws IOException
{
67 n
= Integer
.parseInt(in
.readLine());
68 checkBounds(n
, 1, 100, "n");
72 for (int i
= 0; i
< n
; i
++) {
73 StringTokenizer st
= new StringTokenizer(in
.readLine());
74 x
[i
] = Integer
.parseInt(st
.nextToken());
75 y
[i
] = Integer
.parseInt(st
.nextToken());
76 z
[i
] = Integer
.parseInt(st
.nextToken());
79 facets
= new ArrayList
<List
<Integer
>>();
80 for (int i
= 0; i
< n
; i
++) {
81 for (int j
= i
+ 1; j
< n
; j
++) {
83 for (int k
= j
+ 1; k
< n
; k
++) {
84 vectorProduct(i
, j
, k
);
90 boolean negative
= false;
91 boolean positive
= false;
92 for (int u
= 0; u
< n
; u
++) {
93 long dist
= a
* x
[u
] + b
* y
[u
] + c
* z
[u
] + d
;
96 } else if (dist
> 0) {
99 if ((u
< k
) && (u
!= i
) && (u
!= j
)) {
104 if (positive
&& negative
) {
108 List
<Integer
> facet
= new ArrayList
<Integer
>();
112 for (int u
= k
+ 1; u
< n
; u
++) {
113 if (a
* x
[u
] + b
* y
[u
] + c
* z
[u
] + d
== 0) {
117 // System.err.println(Arrays.toString(facet.toArray()));
118 checkConvexFacet(a
, b
, c
, d
, facet
);
123 check(facets
.size() > 1, "polyhedron is degenerate");
125 long totalVolume
= 0;
129 for (List
<Integer
> facet
: facets
) {
130 int m
= facet
.size();
131 int num1
= facet
.get(0);
132 for (int i
= 0; i
< m
; i
++) {
133 int num2
= facet
.get(i
);
134 int num3
= facet
.get((i
+ 1) % m
);
135 long volume
= calcVolume(0, num1
, num2
, num3
);
136 totalVolume
+= volume
;
137 x0
+= Math
.abs(volume
) * (x
[num1
] + x
[num2
] + x
[num3
] + x
[0]);
138 y0
+= Math
.abs(volume
) * (y
[num1
] + y
[num2
] + y
[num3
] + y
[0]);
139 z0
+= Math
.abs(volume
) * (z
[num1
] + z
[num2
] + z
[num3
] + z
[0]);
142 xc
= 1.0 * x0
/ totalVolume
/ 4.0;
143 yc
= 1.0 * y0
/ totalVolume
/ 4.0;
144 zc
= 1.0 * z0
/ totalVolume
/ 4.0;
145 // System.err.println(xc + " " + yc + " " + zc);
146 // System.err.println(totalVolume);
148 minDist
= Double
.MAX_VALUE
;
149 for (List
<Integer
> facet
: facets
) {
150 vectorProduct(facet
.get(0), facet
.get(1), facet
.get(2));
151 double norm
= Math
.sqrt(vpa
* vpa
+ vpb
* vpb
+ vpc
* vpc
);
152 double dist
= (vpa
* xc
+ vpb
* yc
+ vpc
* zc
+ vpd
) / norm
;
153 minDist
= Math
.min(minDist
, Math
.abs(dist
));
157 private long calcVolume(int a
, int b
, int c
, int d
) {
158 vectorProduct(a
, c
, d
);
159 return Math
.abs((x
[b
] - x
[a
]) * vpa
+ (y
[b
] - y
[a
]) * vpb
+ (z
[b
] - z
[a
]) * vpc
);
163 private void solve() throws IOException
{
164 Polyhedron p1
= new Polyhedron();
165 Polyhedron p2
= new Polyhedron();
166 out
.printf("%.6f\n", p1
.minDist
+ p2
.minDist
);
169 public static void main(String
[] args
) {
170 new Thread(new asteroids_rs()).start();
174 String problem
= getClass().getName().split("_")[0];
176 Locale
.setDefault(Locale
.US
);
177 in
= new BufferedReader(new FileReader(new File(problem
+ ".in")));
178 out
= new PrintWriter(new File(problem
+ ".out"));
182 } catch (IOException e
) {