結果
問題 | No.199 星を描こう |
ユーザー | aaa |
提出日時 | 2015-05-05 13:40:35 |
言語 | Java21 (openjdk 21) |
結果 |
AC
|
実行時間 | 134 ms / 2,000 ms |
コード長 | 9,948 bytes |
コンパイル時間 | 2,483 ms |
コンパイル使用メモリ | 92,940 KB |
実行使用メモリ | 56,060 KB |
最終ジャッジ日時 | 2024-06-09 13:50:50 |
合計ジャッジ時間 | 6,718 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 116 ms
53,880 KB |
testcase_01 | AC | 121 ms
53,796 KB |
testcase_02 | AC | 122 ms
53,996 KB |
testcase_03 | AC | 129 ms
53,968 KB |
testcase_04 | AC | 127 ms
54,220 KB |
testcase_05 | AC | 128 ms
53,892 KB |
testcase_06 | AC | 128 ms
54,312 KB |
testcase_07 | AC | 123 ms
53,828 KB |
testcase_08 | AC | 120 ms
56,060 KB |
testcase_09 | AC | 117 ms
54,084 KB |
testcase_10 | AC | 108 ms
53,032 KB |
testcase_11 | AC | 122 ms
54,016 KB |
testcase_12 | AC | 115 ms
54,012 KB |
testcase_13 | AC | 108 ms
52,860 KB |
testcase_14 | AC | 121 ms
54,136 KB |
testcase_15 | AC | 118 ms
54,184 KB |
testcase_16 | AC | 120 ms
54,184 KB |
testcase_17 | AC | 110 ms
53,444 KB |
testcase_18 | AC | 107 ms
53,420 KB |
testcase_19 | AC | 102 ms
52,900 KB |
testcase_20 | AC | 118 ms
53,828 KB |
testcase_21 | AC | 118 ms
53,724 KB |
testcase_22 | AC | 123 ms
54,060 KB |
testcase_23 | AC | 117 ms
53,916 KB |
testcase_24 | AC | 120 ms
53,048 KB |
testcase_25 | AC | 134 ms
54,212 KB |
testcase_26 | AC | 126 ms
53,948 KB |
testcase_27 | AC | 119 ms
54,048 KB |
ソースコード
package y199; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Scanner; public class Main { static final double EPS = 1.0e-8; final P origin = new P(0, 0); final double rad = 180/Math.PI; /* *基本 * */ //ベクトルのなす角度p0→p1, p1→p2のなす角。劣角限定 @ac static double angle(P p0, P p1, P p2) { P v = p1.sub(p0); P u = p2.sub(p1); return Math.acos((-v.x*u.x -v.y*u.y)/ (v.norm()*u.norm())); } //ベクトルpをlに射影 @ac static P proj(L l, P p) { double t = inp(p.sub(l.s), l.s.sub(l.t)) / l.s.sub(l.t).norm2(); P tp = l.s.sub(l.t); return new P(l.s.x + t*tp.x, l.s.y + t*tp.y); } static P refl(L l, P p) { P tp = proj(l, p).sub(p); return new P(p.x + 2*tp.x, p.y + 2*tp.y); } //内積 static double inp(P p1, P p2) { return p1.x*p2.x + p1.y*p2.y; } //外積 static double extp(P p1, P p2) { return p1.x*p2.y - p2.x*p1.y; } //点の進行方向 // 1 : ccw, -1: cw, 2: c--a--b, -2: a--b--c, 0:a--c--b(or a--c=b) //a b c が反時計 1 //a b c が時計 -1 //直線a b上にcが乗ってると0 static int ccw(P a, P b, P c) { P p = b.sub(a), q = c.sub(a); if (extp(p, q) > EPS) return +1; if (extp(p, q) < -EPS) return -1; if (inp(p, q) < -EPS) return +2; if (p.norm() + EPS < q.norm()) return -2; return 0; } /* * 交差判定など * */ //直線の交差判定と static boolean intersectLL(L l, L m) { return Math.abs(extp(l.t.sub(l.s), m.t.sub(m.s))) > EPS || // non-parallel Math.abs(extp(l.t.sub(l.s), m.s.sub(l.s))) < EPS; // same line } static boolean intersectLS(L l, L s) { return extp(l.t.sub(l.s), s.s.sub(l.s))* // s.s is left of l extp(l.t.sub(l.s), s.t.sub(l.t)) < EPS; // s.t is right of l } static boolean intersectSS(L s, L t) { return ccw(s.s,s.t,t.s)*ccw(s.s,s.t,t.t) <= 0 && ccw(t.s,t.t,s.s)*ccw(t.s,t.t,s.t) <= 0; } static boolean intersectSP(L s, P p) { return ccw(s.s, s.t, p) == 0; //return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality } /* * 距離など */ static double distanceLP(L l, P p) { return p.sub(proj(l, p)).norm(); } static double distanceLL(L l, L m) { return intersectLL(l, m) ? 0 : distanceLP(l, m.s); } static double distanceLS(L l, L s) { if (intersectLS(l, s)) return 0; return Math.min(distanceLP(l, s.s), distanceLP(l, s.t)); } static double distanceSP(L s, P p) { P r = proj(s, p); if (intersectSP(s, r)) return r.sub(p).norm(); return Math.min(s.s.sub(p).norm(), s.t.sub(p).norm()); } static double distanceSS(L s, L t) { if (intersectSS(s, t)) return 0; return Math.min(Math.min(distanceSP(s, t.s), distanceSP(s, t.t)), Math.min(distanceSP(t, s.s), distanceSP(t, t.t))); } /* * 交点 * */ //直線の交点@ac //直線と直線の交点 P isLL(P p1, P p2, P q1, P q2) { double d = q2.sub(q1).det(p2.sub(p1)); if (Math.abs(d) < EPS) return null; return p1.add(p2.sub(p1).mul(q2.sub(q1).det(q1.sub(p1)) / d)); } //Precondition: 平行でない static P crosspoint(L l, L m) { double A = extp(l.t.sub(l.s), m.t.sub(m.s)); double B = extp(l.t.sub(l.s), l.t.sub(m.s)); if (Math.abs(A) < EPS && Math.abs(B) < EPS) return m.s; // same line if (Math.abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!! P tp = m.t.sub(m.s); return new P(m.s.x + B/A*tp.x, m.s.y + B/A*tp.y); } //平行判定? static boolean isParallel(L l, L m) { double A = extp(l.t.sub(l.s), m.t.sub(m.s)); return (Math.abs(A) < EPS); } //直交判定? static boolean isOrthogonal(L l, L m) { double A = inp(l.t.sub(l.s), m.t.sub(m.s)); return (Math.abs(A) < EPS); } static P crosspoint(P s1, P t1, P s2, P t2) { double A = extp(t1.sub(s1), t2.sub(s2)); double B = extp(t1.sub(s1), t1.sub(s2)); if (Math.abs(A) < EPS && Math.abs(B) < EPS) return s2; // same line if (Math.abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!! P tp = t2.sub(s2); return new P(s2.x + B/A*tp.x, s2.y + B/A*tp.y); } /* * * 面積系 */ //多角形の面積 static double area(P[] p) { double s = 0; for(int i=0; i<p.length; i++) { int j = (i+1)%p.length; s += extp(p[i], p[j]); } s /= 2; //誤差を避けたいときには割らない return Math.abs(s); } //円c1, c2の共通部分の面積 static double cc_area(Circle c1, Circle c2) { double d = c1.p.sub(c2.p).norm(); if(c1.r + c2.r <= d+EPS) { return 0; } else if(d <= Math.abs(c1.r - c2.r) + EPS) { double r = Math.min(c1.r, c2.r); return r*r*Math.PI; } else { double rc = (d*d + c1.r*c1.r - c2.r*c2.r) / (2*d); double theta = Math.acos(rc / c1.r); double phi = Math.acos((d - rc) / c2.r); return c1.r*c1.r*theta + c2.r*c2.r*phi - d*c1.r*Math.sin(theta); } } /* * 凸多角形 */ //凸性判定 //Precondition: 3点以上 static boolean isConvex(P[] p) { for (int i = 0; i < p.length; ++i) { int next = (i+1)%p.length; int prev = (i-1+p.length)%p.length; if (ccw(p[prev], p[i], p[next]) > 0) { return false; } } return true; } //凸包を求める //Precondition: 3点以上 static P[] convex_hull(P[] p) { int n = p.length, k = 0; // p = Arrays.copyOf(p, p.length);//pの順序の保守が必要な場合 Arrays.sort(p, 0, n, new Comparator<P>() { @Override public int compare(P p1, P p2) { return p1.x>p2.x?-1:p1.x<p2.x?1:p1.y>p2.y?-1:p1.y<p2.y?1:0; }}); P[] ch = new P[2*n]; for (int i=0; i<n; ch[k++] = p[i++]) // lower-hull while (k >= 2 && ccw(ch[k-2], ch[k-1], p[i]) <= 0) --k; for (int i = n-2, t = k+1; i >= 0; ch[k++] = p[i--]) // upper-hull while (k >= t && ccw(ch[k-2], ch[k-1], p[i]) <= 0) --k; return Arrays.copyOf(ch, k-1); } //最遠点対距離 //Precondition: p[]は反時計回りの凸包 static double farthest(P[] p) { int is = 0, js = 0; for (int i = 1; i < p.length; ++i) { if (p[i].y > p[is].y) is = i; if (p[i].y < p[js].y) js = i; } double maxd = p[is].sub(p[js]).norm(); int i=is, j=js; //int maxi=i, maxj=j; do { int ni = (i+1)%p.length; int nj = (j+1)%p.length; if (extp(p[ni].sub(p[i]), p[nj].sub(p[j])) >= 0) j = (j+1) % p.length; else i = (i+1) % p.length; if (p[i].sub(p[j]).norm() > maxd) { maxd = p[i].sub(p[j]).norm(); //maxi = i; maxj=j; } } while (i != is || j != js); return maxd; /* farthest pair is (maxi, maxj). */ } //凸包の切断、lの左側を残す static P[] convex_cut(P[] p, L l) { List<P> q = new ArrayList<P>(); for (int i = 0; i < p.length; ++i) { P a= p[i], b = p[(i+1)%p.length]; if (ccw(l.s, l.t, a) != -1) q.add(a); if (ccw(l.s, l.t, a)*ccw(l.s, l.t, b) < 0) q.add(crosspoint(new L(a, b), l)); } return q.toArray(new P[q.size()]); } /* * データ構造など * */ static class P { double x,y; P(double _x, double _y) { x = _x; y = _y; } public String toString() {return "(" +x+", "+ y +")";} P sub(P p) { return new P(x-p.x, y-p.y); } P add(P p){ return new P(x+p.x, y+p.y); } P mul(double m){ return new P(x*m, y*m); } P div(double d){ return new P(x/d, y/d); } double abs(){ return Math.sqrt(abs2()); } double abs2(){ return x*x+y*y; } double arg(){ return Math.atan2(y, x); } double myarg() { double arg = Math.atan2(y, x); if(arg < 0) return 2.0*Math.PI + arg; else return arg; } // inner product double dot(P p){ return x*p.x+y*p.y; } // outer product double det(P p){ return x*p.y-y*p.x; } P rot90(){ return new P(-y, x); } // conjugation P conj(){ return new P(x, -y); } double norm() { return Math.sqrt(norm2()); } double norm2() { return x*x + y*y; } } //直線or線分のクラス static class L { P s,t; L(P _s, P _t) { s = _s; t = _t; } public String toString() {return s.toString() + " -> " + t.toString();} } //円のクラス中心pで半径r static class Circle { P p; double r; Circle(P _p, double _r) { p = _p; r = _r; } public String toString() { return "center=" + p.toString() + " radius=" + r; } } //点 p をから引いた接線の接点 P[] tanCP(P c, double r, P p) { double x = p.sub(c).abs2(); double d = x - r * r; if (d < -EPS) return new P[0]; if (d < 0) d = 0; P q1 = p.sub(c).mul(r * r / x); P q2 = p.sub(c).mul(-r * Math.sqrt(d) / x).rot90(); return new P[]{c.add(q1.sub(q2)), c.add(q1.add(q2))}; } //2円の交点 P[] isCC(P c1, double r1, P c2, double r2) { double x = c1.sub(c2).abs2(); double y = ((r1 * r1 - r2 * r2) / x + 1) / 2; double d = r1 * r1 / x - y * y; if (d < -EPS) return new P[0]; if (d < 0) d = 0; P q1 = c1.add(c2.sub(c1).mul(y)); P q2 = c2.sub(c1).mul(Math.sqrt(d)).rot90(); return new P[]{q1.sub(q2), q1.add(q2)}; } static P cor[]; static boolean rec(int i, int bit, int[] perm) { if(i == 5) { L line[] = new L[5]; for(int j = 0; j < 5; j++) { line[j] = new L(cor[perm[j]], cor[perm[(j+1)%5]]); } for(int j = 0; j < 5; j++) { L a = line[j]; L b = line[(j+2)%5]; L c = line[(j+3)%5]; if(!intersectSS(a, b) || !intersectSS(a, c)) { return false; } } return true; } for(int j = 0; j < 5; j++) { if(((1<<j)&bit) != 0) continue; perm[i] = j; if(rec(i+1, bit|(1<<j), perm)) { return true; } } return false; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); cor = new P[5]; for(int i = 0; i < 5; i++) { cor[i] = new P(sc.nextInt(), sc.nextInt()); } for(int i = 0; i < 5; i++) for(int j = 0; j < 5; j++) for(int k = 0; k < 5; k++) { if(Integer.bitCount((1<<i)|(1<<j)|(1<<k)) != 3) continue; if(ccw(cor[i], cor[j], cor[k]) == 0) { System.out.println("NO"); return; } } if(rec(0, 0, new int[5])) { System.out.println("YES"); } else { System.out.println("NO"); } } }