1 import java
.util
.Scanner
;
2 import java
.util
.Random
;
3 import java
.io
.PrintWriter
;
4 import java
.io
.FileNotFoundException
;
5 import static java
.lang
.Math
.*;
10 * @author Andrew Stankevich
19 Polyhedron(int[][] v
) {
24 for (int i
= 0; i
< n
; i
++) {
31 Polyhedron(int[] x
, int[] y
, int[] z
) {
45 void shuffleVertices() {
46 for (int i
= 0; i
< n
; i
++) {
47 int j
= rnd
.nextInt(i
+ 1);
48 int t
= x
[i
]; x
[i
] = x
[j
]; x
[j
] = t
;
49 t
= y
[i
]; y
[i
] = y
[j
]; y
[j
] = t
;
50 t
= z
[i
]; z
[i
] = z
[j
]; z
[j
] = t
;
54 void shift(int dx
, int dy
, int dz
) {
55 for (int i
= 0; i
< n
; i
++) {
63 boolean[] ok
= new boolean[n
];
64 for (int i
= 0; i
< n
; i
++) {
65 for (int j
= i
+ 1; j
< n
; j
++) {
66 for (int k
= j
+ 1; k
< n
; k
++) {
67 long a
= (y
[j
] - y
[i
]) * (z
[k
] - z
[i
]) - (y
[k
] - y
[i
]) * (z
[j
] - z
[i
]);
68 long b
= (z
[j
] - z
[i
]) * (x
[k
] - x
[i
]) - (z
[k
] - z
[i
]) * (x
[j
] - x
[i
]);
69 long c
= (x
[j
] - x
[i
]) * (y
[k
] - y
[i
]) - (x
[k
] - x
[i
]) * (y
[j
] - y
[i
]);
70 if (a
== 0 && b
== 0 && c
== 0) {
73 long d
= -(a
* x
[i
] + b
* y
[i
] + c
* z
[i
]);
78 for (int l
= 0; l
< n
; l
++) {
79 long v
= a
* x
[l
] + b
* y
[l
] + c
* z
[l
] + d
;
80 if (v
< 0) neg
= true;
81 if (v
> 0) pos
= true;
84 ok
[i
] = ok
[j
] = ok
[k
] = true;
89 for (int i
= 0; i
< n
; i
++) {
110 boolean[] ok
= new boolean[n
];
111 for (int i
= 0; i
< n
; i
++) {
112 for (int j
= i
+ 1; j
< n
; j
++) {
116 for (int k
= 0; k
< n
; k
++) {
117 int vp
= (x
[j
] - x
[i
]) * (y
[k
] - y
[i
]) - (x
[k
] - x
[i
]) * (y
[j
] - y
[i
]);
118 if (vp
> 0) pos
= true;
119 if (vp
< 0) neg
= true;
126 ok
[i
] = ok
[j
] = true;
130 for (int i
= 0; i
< n
; i
++) {
144 Vector(int x
, int y
, int z
) {
153 void printTest(Polyhedron a
, Polyhedron b
) throws FileNotFoundException
{
154 System
.err
.println("Printing test " + testNo
);
155 PrintWriter out
= new PrintWriter("" + testNo
/ 10 + testNo
% 10);
157 for (int i
= 0; i
< a
.n
; i
++) {
158 out
.println(a
.x
[i
] + " " + a
.y
[i
] + " " + a
.z
[i
]);
161 for (int i
= 0; i
< b
.n
; i
++) {
162 out
.println(b
.x
[i
] + " " + b
.y
[i
] + " " + b
.z
[i
]);
168 Random rnd
= new Random(5265485256544745L);
170 void generateSample() throws FileNotFoundException
{
171 Polyhedron a
= new Polyhedron(
182 Polyhedron b
= new Polyhedron(
193 void generateMax() throws FileNotFoundException
{
194 Polyhedron a
= new Polyhedron(
205 for (int i
= 0; i
< 8; i
++) {
206 a
.x
[i
] = a
.x
[i
] * 9999 + 1;
207 a
.y
[i
] = a
.y
[i
] * 9999 + 1;
208 a
.z
[i
] = a
.z
[i
] * 9999 + 1;
210 Polyhedron b
= new Polyhedron(
221 for (int i
= 0; i
< 8; i
++) {
222 b
.x
[i
] = b
.x
[i
] * 10000 - 10000;
223 b
.y
[i
] = b
.y
[i
] * 10000 - 10000;
224 b
.z
[i
] = b
.z
[i
] * 10000 - 10000;
229 Polygon
generateOval(int n
) {
230 Polygon r
= new Polygon(n
);
232 int rx
= rnd
.nextInt(300) + 1;
233 int ry
= rnd
.nextInt(300) + 1;
234 int cx
= rnd
.nextInt(601) - 300;
235 int cy
= rnd
.nextInt(601) - 300;
237 for (int i
= 0; i
< n
; i
++) {
240 beta
= rnd
.nextDouble() * (2 * PI
- alpha
) / (n
- i
) * 2;
241 } while (beta
< 1e-3 || alpha
+ beta
> 2 * PI
- (n
- i
) * 1e-3);
243 r
.x
[i
] = (int) Math
.round(cx
+ rx
* cos(alpha
));
244 r
.y
[i
] = (int) Math
.round(cx
+ rx
* sin(alpha
));
246 } while (!r
.isConvex());
250 Vector
randomVector(int minc
, int maxc
) {
251 return new Vector(rnd
.nextInt(maxc
- minc
+ 1) + minc
, rnd
.nextInt(maxc
- minc
+ 1) + minc
, rnd
.nextInt(maxc
- minc
+ 1) + minc
);
254 int det3(int a1
, int a2
, int a3
, int b1
, int b2
, int b3
, int c1
, int c2
, int c3
) {
255 return a1
* b2
* c3
+ a2
* b3
* c1
+ a3
* b1
* c2
- a1
* b3
* c2
- a2
* b1
* c3
- a3
* b2
* c1
;
258 Polyhedron
generatePyramid(int n
) {
259 Polygon base
= generateOval(n
- 1);
262 oi
= randomVector(-5, 5);
263 oj
= randomVector(-5, 5);
264 ok
= randomVector(-5, 5);
265 } while (det3(oi
.x
, oi
.y
, oi
.z
, oj
.x
, oj
.y
, oj
.z
, ok
.x
, ok
.y
, ok
.z
) == 0);
266 Polyhedron r
= new Polyhedron(n
);
267 for (int i
= 0; i
< n
- 1; i
++) {
268 r
.x
[i
] = oi
.x
* base
.x
[i
] + oj
.x
* base
.y
[i
];
269 r
.y
[i
] = oi
.y
* base
.x
[i
] + oj
.y
* base
.y
[i
];
270 r
.z
[i
] = oi
.z
* base
.x
[i
] + oj
.z
* base
.y
[i
];
272 int d
= rnd
.nextInt(100) + 1;
273 r
.x
[n
- 1] = ok
.x
* d
;
274 r
.y
[n
- 1] = ok
.y
* d
;
275 r
.z
[n
- 1] = ok
.z
* d
;
279 Polyhedron
generatePrism(int n
) {
280 Polygon base
= generateOval(n
);
283 oi
= randomVector(-5, 5);
284 oj
= randomVector(-5, 5);
285 ok
= randomVector(-5, 5);
286 } while (det3(oi
.x
, oi
.y
, oi
.z
, oj
.x
, oj
.y
, oj
.z
, ok
.x
, ok
.y
, ok
.z
) == 0);
287 Polyhedron r
= new Polyhedron(2 * n
);
288 int d
= rnd
.nextInt(50) + 1;
289 for (int i
= 0; i
< n
; i
++) {
290 r
.x
[i
] = oi
.x
* base
.x
[i
] + oj
.x
* base
.y
[i
];
291 r
.y
[i
] = oi
.y
* base
.x
[i
] + oj
.y
* base
.y
[i
];
292 r
.z
[i
] = oi
.z
* base
.x
[i
] + oj
.z
* base
.y
[i
];
293 r
.x
[n
+ i
] = oi
.x
* base
.x
[i
] + oj
.x
* base
.y
[i
] + ok
.x
* d
;
294 r
.y
[n
+ i
] = oi
.y
* base
.x
[i
] + oj
.y
* base
.y
[i
] + ok
.y
* d
;
295 r
.z
[n
+ i
] = oi
.z
* base
.x
[i
] + oj
.z
* base
.y
[i
] + ok
.z
* d
;
300 Polyhedron
generateEllipsoid(int n
) {
305 oi
= randomVector(-500, 500);
306 oj
= randomVector(-500, 500);
307 ok
= randomVector(-500, 500);
308 } while (det3(oi
.x
, oi
.y
, oi
.z
, oj
.x
, oj
.y
, oj
.z
, ok
.x
, ok
.y
, ok
.z
) == 0);
309 r
= new Polyhedron(n
);
310 for (int i
= 0; i
< n
; i
++) {
311 double phi
= rnd
.nextDouble() * 2 * PI
;
312 double rho
= rnd
.nextDouble() * PI
- PI
/ 2;
313 r
.x
[i
] = (int) Math
.round(oi
.x
* cos(phi
) * cos(rho
) + oj
.x
* sin(phi
) * cos(rho
) + ok
.x
* sin(rho
));
314 r
.y
[i
] = (int) Math
.round(oi
.y
* cos(phi
) * cos(rho
) + oj
.y
* sin(phi
) * cos(rho
) + ok
.y
* sin(rho
));
315 r
.z
[i
] = (int) Math
.round(oi
.z
* cos(phi
) * cos(rho
) + oj
.z
* sin(phi
) * cos(rho
) + ok
.z
* sin(rho
));
317 } while (!r
.isConvex());
322 public void run() throws FileNotFoundException
{
325 System
.err
.println("Tetrahedrons");
326 for (int i
= 1; i
<= 5; i
++) {
327 Polyhedron a
= generatePyramid(4);
328 Polyhedron b
= generatePyramid(4);
329 a
.shift(-5000, -5000, -5000);
330 b
.shift(5000, 5000, 5000);
334 System
.err
.println("Large pyramids");
335 for (int i
= 1; i
<= 6; i
++) {
336 Polyhedron a
= generatePyramid(i
* 10);
337 Polyhedron b
= generatePyramid(i
* 10);
338 a
.shift(-5000, -5000, -5000);
339 b
.shift(5000, 5000, 5000);
343 System
.err
.println("Random pyramids");
344 for (int i
= 1; i
<= 5; i
++) {
345 Polyhedron a
= generatePyramid(rnd
.nextInt(56) + 4);
346 Polyhedron b
= generatePyramid(rnd
.nextInt(56) + 4);
347 a
.shift(-5000, -5000, -5000);
348 b
.shift(5000, 5000, 5000);
352 System
.err
.println("Triangular prisms");
353 for (int i
= 1; i
<= 5; i
++) {
354 Polyhedron a
= generatePrism(3);
355 Polyhedron b
= generatePrism(3);
356 a
.shift(-5000, -5000, -5000);
357 b
.shift(5000, 5000, 5000);
361 System
.err
.println("Large prisms");
362 for (int i
= 1; i
<= 5; i
++) {
363 Polyhedron a
= generatePrism(i
* 6);
364 Polyhedron b
= generatePrism(i
* 6);
365 a
.shift(-5000, -5000, -5000);
366 b
.shift(5000, 5000, 5000);
370 System
.err
.println("Random prisms");
371 for (int i
= 1; i
<= 5; i
++) {
372 Polyhedron a
= generatePrism(rnd
.nextInt(28) + 3);
373 Polyhedron b
= generatePrism(rnd
.nextInt(28) + 3);
374 a
.shift(-5000, -5000, -5000);
375 b
.shift(5000, 5000, 5000);
379 System
.err
.println("Large ellipsoids");
380 for (int i
= 2; i
<= 10; i
++) {
381 Polyhedron a
= generateEllipsoid(5 * i
);
382 Polyhedron b
= generateEllipsoid(5 * i
);
383 a
.shift(-5000, -5000, -5000);
384 b
.shift(5000, 5000, 5000);
388 System
.err
.println("Random ellipsoids");
389 for (int i
= 1; i
<= 5; i
++) {
390 Polyhedron a
= generateEllipsoid(10 + rnd
.nextInt(51));
391 Polyhedron b
= generateEllipsoid(10 + rnd
.nextInt(51));
392 a
.shift(-5000, -5000, -5000);
393 b
.shift(5000, 5000, 5000);
400 public static void main(String
[] args
) throws FileNotFoundException
{