Problem:
Problem G: Star

Problem

半径1の円に内接する正N/K角形の面積を求めよ。

ただし、正N/K角形を
「円周上に等間隔にN個の点を取り、
K-1個おきにそれぞれの点を結んだ一番外側の図形」
と定義する。

例えば、5/2角形は次のように描くことができる。
まず、半径1の円周上に等間隔に5つの点を取る。

次に、それぞれの点を2-1=1つおきに結ぶ。

一番外側の図形が正5/2角形になる。

Input

入力は以下の形式で与えられる。

N K

2つの整数 N, K が1行に与えられる。

Constraints

入力は以下の制約を満たす。

5 ≤ N ≤ 106

1 < K < N/2

N,Kは互いに素である整数

Output

半径1の円に内接する正N/K角形の面積を1行に出力せよ。10-5以下の誤差が許容される。

Sample Input 1

5 2

Sample Output 1

1.12256994

正5/2角形は上記の図形である。

Sample Input 2

20 3

Sample Output 2

2.93114293

正20/3角形は下のような図形である。

Sample Input 3

7 3

Sample Output 3

1.08395920

Sample Input 4

100000 3

Sample Output 4

3.14159265

Solution in JAVA (judge verdict: Accepted)

import java.util.Scanner;

public class Main {

	static Scanner sc = new Scanner(System.in);

	public static void main(String[] args) {
		int N = sc.nextInt();
		int K = sc.nextInt();
		double radDiff = Math.PI * 2 / N;
		Point p1f = new Point(1, 0);
		Point p1t = new Point(Math.cos(radDiff * K), Math.sin(radDiff * K));
		Point p2f = new Point(Math.cos(radDiff), Math.sin(radDiff));
		Point p2t = new Point(Math.cos(-radDiff * (K - 1)), Math.sin(-radDiff * (K - 1)));
		Point cross = getIntersectPoint(p1f, p1t, p2f, p2t);
		double dx1 = p1f.x - cross.x;
		double dy1 = p1f.y - cross.y;
		double dx2 = p2f.x - cross.x;
		double dy2 = p2f.y - cross.y;
		double area = (dx1 * dy2 - dx2 * dy1) / 2;
		double all = (p1f.x * p2f.y - p2f.x * p1f.y) / 2;
		System.out.printf("%.9f\n", (all - area) * N);
	}

	static Point getIntersectPoint(Point p1, Point p2, Point p3, Point p4) {
		double x1 = p1.x;
		double y1 = p1.y;
		double x2 = p2.x;
		double y2 = p2.y;
		double x3 = p3.x;
		double y3 = p3.y;
		double x4 = p4.x;
		double y4 = p4.y;
		double dx2 = x4 - x3;
		double dy2 = y4 - y3;
		double s1 = dx2 * (y1 - y3) - (dy2 * (x1 - x3));
		double s2 = dx2 * (y3 - y2) - (dy2 * (x3 - x2));
		double ss = s1 + s2;
		if (ss == 0) return null;
		double sr = s1 / ss;
		double cx1 = x1 + ((x2 - x1) * sr);
		double cy1 = y1 + ((y2 - y1) * sr);
		if (Double.compare(cx1, x1) * Double.compare(cx1, x2) > 0) {
			return null;
		}
		if (Double.compare(cy1, y1) * Double.compare(cy1, y2) > 0) {
			return null;
		}
		if (Double.compare(cx1, x3) * Double.compare(cx1, x4) > 0) {
			return null;
		}
		if (Double.compare(cy1, y3) * Double.compare(cy1, y4) > 0) {
			return null;
		}
		return new Point(cx1, cy1);
	}

	static class Point {
		double x, y;

		public Point(double x, double y) {
			this.x = x;
			this.y = y;
		}
	}

}