Adding some more judges, here and there.
[and.git] / NEERC / asteroids / tests / doall.java
blob17e370d7609231127dc4d31ecd68fb156822bda0
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.*;
7 /**
8 * doallSpecial
10 * @author Andrew Stankevich
12 public class doall {
13 class Polyhedron {
14 int n;
15 int[] x;
16 int[] y;
17 int[] z;
19 Polyhedron(int[][] v) {
20 n = v.length;
21 x = new int[n];
22 y = new int[n];
23 z = new int[n];
24 for (int i = 0; i < n; i++) {
25 x[i] = v[i][0];
26 y[i] = v[i][1];
27 z[i] = v[i][2];
31 Polyhedron(int[] x, int[] y, int[] z) {
32 n = x.length;
33 this.x = x.clone();
34 this.y = y.clone();
35 this.z = z.clone();
38 Polyhedron(int n) {
39 this.n = n;
40 x = new int[n];
41 y = new int[n];
42 z = new int[n];
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++) {
56 x[i] += dx;
57 y[i] += dy;
58 z[i] += dz;
62 boolean isConvex() {
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) {
71 return false;
73 long d = -(a * x[i] + b * y[i] + c * z[i]);
75 boolean pos = false;
76 boolean neg = false;
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;
83 if (!(pos && neg)) {
84 ok[i] = ok[j] = ok[k] = true;
89 for (int i = 0; i < n; i++) {
90 if (!ok[i]) {
91 return false;
94 return true;
98 class Polygon {
99 int n;
100 int[] x;
101 int[] y;
103 Polygon(int n) {
104 this.n = n;
105 x = new int[n];
106 y = new int[n];
109 boolean isConvex() {
110 boolean[] ok = new boolean[n];
111 for (int i = 0; i < n; i++) {
112 for (int j = i + 1; j < n; j++) {
113 boolean pos = false;
114 boolean neg = false;
115 int zer = 0;
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;
120 if (vp == 0) zer++;
122 if (zer > 2) {
123 return false;
125 if (!(pos && neg)) {
126 ok[i] = ok[j] = true;
130 for (int i = 0; i < n; i++) {
131 if (!ok[i]) {
132 return false;
135 return true;
139 class Vector {
140 int x;
141 int y;
142 int z;
144 Vector(int x, int y, int z) {
145 this.x = x;
146 this.y = y;
147 this.z = z;
151 int testNo = 1;
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);
156 out.println(a.n);
157 for (int i = 0; i < a.n; i++) {
158 out.println(a.x[i] + " " + a.y[i] + " " + a.z[i]);
160 out.println(b.n);
161 for (int i = 0; i < b.n; i++) {
162 out.println(b.x[i] + " " + b.y[i] + " " + b.z[i]);
164 out.close();
165 testNo++;
168 Random rnd = new Random(5265485256544745L);
170 void generateSample() throws FileNotFoundException {
171 Polyhedron a = new Polyhedron(
172 new int[][]
173 {{0, 0, 0},
174 {0, 0, 1},
175 {0, 1, 0},
176 {0, 1, 1},
177 {1, 0, 0},
178 {1, 0, 1},
179 {1, 1, 0},
180 {1, 1, 1}}
182 Polyhedron b = new Polyhedron(
183 new int[][]
184 {{0, 0, 5},
185 {1, 0, 6},
186 {-1, 0, 6},
187 {0, 1, 6},
188 {0, -1, 6}}
190 printTest(a, b);
193 void generateMax() throws FileNotFoundException {
194 Polyhedron a = new Polyhedron(
195 new int[][]
196 {{0, 0, 0},
197 {0, 0, 1},
198 {0, 1, 0},
199 {0, 1, 1},
200 {1, 0, 0},
201 {1, 0, 1},
202 {1, 1, 0},
203 {1, 1, 1}}
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(
211 new int[][]
212 {{0, 0, 0},
213 {0, 0, 1},
214 {0, 1, 0},
215 {0, 1, 1},
216 {1, 0, 0},
217 {1, 0, 1},
218 {1, 1, 0},
219 {1, 1, 1}}
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;
226 printTest(a, b);
229 Polygon generateOval(int n) {
230 Polygon r = new Polygon(n);
231 do {
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;
236 double alpha = 0;
237 for (int i = 0; i < n; i++) {
238 double beta;
239 do {
240 beta = rnd.nextDouble() * (2 * PI - alpha) / (n - i) * 2;
241 } while (beta < 1e-3 || alpha + beta > 2 * PI - (n - i) * 1e-3);
242 alpha += beta;
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());
247 return r;
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);
260 Vector oi, oj, ok;
261 do {
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;
276 return r;
279 Polyhedron generatePrism(int n) {
280 Polygon base = generateOval(n);
281 Vector oi, oj, ok;
282 do {
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;
297 return r;
300 Polyhedron generateEllipsoid(int n) {
301 Polyhedron r;
302 do {
303 Vector oi, oj, ok;
304 do {
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());
318 return r;
322 public void run() throws FileNotFoundException {
323 generateSample();
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);
331 printTest(a, b);
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);
340 printTest(a, b);
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);
349 printTest(a, b);
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);
358 printTest(a, b);
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);
367 printTest(a, b);
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);
376 printTest(a, b);
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);
385 printTest(a, b);
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);
394 printTest(a, b);
397 generateMax();
400 public static void main(String[] args) throws FileNotFoundException {
401 new doall().run();