AOJ0187 Stoning Fortune

問題リンク Stoning Fortune

  • 解法

幾何問題です。
3本の線分に0, 1, 2と番号付けしたとして、0と1, 1と2, 2と0の線分の交点を求めます。
交点が存在しなかったら三角形は作れません。
あとは3つの交点でできる三角形の面積を求めて大きさを見るだけです。線分が同じ所で交わって交点が実質3つもない場合は面積0になるので特に気にする必要はないと思います。
※三角形の面積の求め方は色々ありますが「外積 面積」でググると出てくる外積を使った求め方が自分は使いやすいです。多角形にも使えますし、頂点の座標さえ分かっていれば求められるからです。

  • ソース
import java.util.Scanner;

//Stoning Fortune
public class AOJ0187 {

	static class Point {
		public double x;
		public double y;
		public Point(double x_, double y_) {
			x = x_; y=y_;
		}
	}
	static class Line {
		public Point s,t;
		public Line(Point s_, Point t_) {
			s = s_; t = t_;
		}
	}
	static Point crosspoint(Line l, Line m) {
		if(isParallel(l, m)){
			return null;
		}
		  double A = extp(sub(l.t, l.s), sub(m.t, m.s));
		  double B = extp(sub(l.t, l.s), sub(l.t, 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!!!
		  Point tp = sub(m.t, m.s);
		  return new Point(m.s.x + B/A*tp.x, m.s.y + B/A*tp.y);
	}
	static boolean isParallel(Line l, Line m){
		Point a = new Point(l.t.x - l.s.x, l.t.y - l.s.y);
		Point b = new Point(m.t.x - m.s.x, m.t.y - m.s.y);
		if(Math.abs(Math.abs((a.x*b.x + a.y*b.y)/(Math.hypot(a.x, a.y)*Math.hypot(b.x, b.y)) - 1)) < EPS){
			return true;
		}
		return false;
	}
	static final double EPS = 1.0e-8;
	static Point sub(Point p1, Point p2) {
		return new Point(p1.x-p2.x, p1.y-p2.y);
	}
	static double extp(Point p1, Point p2) {
		return p1.x*p2.y - p2.x*p1.y;
	}
	static boolean intersectSS(Line s, Line 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 int ccw(Point a, Point b, Point c) {
		Point p = sub(b, a);
		Point q = sub(c, a);
		if(extp(p, q) > EPS) return 1;		// counter clockwise
		if(extp(p, q) < -EPS)return -1;		// clockwise
		if(inp(p, q) < -EPS) return 2;		// c--a--b on line
		if(Math.abs(norm(p) - norm(q)) < EPS) return -2;	// a--b--c on line
		return 0;				// a--c--b(or a--c=b) on line
	}
	static double inp(Point p1, Point p2) {
		return p1.x*p2.x + p1.y*p2.y;
	}
	static double norm(Point p) {
		return Math.hypot(p.x, p.y);
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true){
			double x1 = sc.nextDouble();
			double y1 = sc.nextDouble();
			double x2 = sc.nextDouble();
			double y2 = sc.nextDouble();
			if(x1==0&&y1==0&&x2==0&&y2==0)break;
			Line[] l = new Line[3];
			l[0] = new Line(new Point(x1, y1), new Point(x2, y2));
			for(int i=1;i<3;i++)l[i]=new Line(new Point(sc.nextDouble(),sc.nextDouble()), new Point(sc.nextDouble(), sc.nextDouble()));
			Point[] c = new Point[3];
			boolean f = true;
			for(int i=0;i<3;i++){
				c[i] = crosspoint(l[i], l[(i+1)%3]);
				if(c[i]==null || !intersectSS(l[i], l[(i+1)%3]))f = false;
			}
			String ans = "";
			if(!f)ans = "kyo";
			else{
				double a = 0;
				for(int i=0;i<3;i++)a+=c[i].x*c[(i+1)%3].y-c[i].y*c[(i+1)%3].x;
				a = Math.abs(a/2);
				if(1900000<=a)ans = "dai-kichi";
				else if(1000000<=a)ans = "chu-kichi";
				else if(100000<=a)ans = "kichi";
				else if(0<a)ans = "syo-kichi";
				else ans = "kyo";
			}
			System.out.println(ans);
		}
	}
}