import java.io.*; import java.math.BigDecimal; import java.math.MathContext; import java.util.*; public class Mark64Fastest { static double[] etienne; public static void initEtienne(int N, int K) { etienne = new double[2001]; etienne[0] = (double)K * (K-1) / (double)(N * (N-1)); for (int i = 1; i < 2001; ++i) { if (N - K >= i) { // i: to remove etienne[i] = etienne[i-1] * (N-K-(i-1)) / (N-2-(i-1)); } else etienne[i] = 0; } } public static void main(String[] args) throws IOException { FastReader fr = new FastReader(); PrintWriter pw = new PrintWriter(System.out); int N = fr.nextInt(), K = fr.nextInt(), D = fr.nextInt(); initEtienne(N, K); double ans = 0; Point[] points = new Point[N]; for (int i = 0; i < N; ++i) points[i] = new Point(Math.round(fr.nextDouble() * 100), Math.round(fr.nextDouble() * 100)); for (int i = 0; i < N; ++i) { List lines = new ArrayList<>(); for (int j = 0; j < N; ++j) if (j != i) lines.add(new Line(points[i], points[j])); lines.sort(Line::compare); int above = 0; int below = 0; for (Line l : lines) { if (l.flip) below++; else above++; } for (int j = 0; j < lines.size(); ) { Line l = lines.get(j); // ========================================= // ==== IDENTIFY COLLINEAR ================= // ========================================= int numFlipped = 0, numNotFlipped = 0; if (l.flip) numFlipped++; else numNotFlipped++; int numMatches = 1; while (j + numMatches < lines.size() && l.dir.cross(lines.get(j + numMatches).dir) == 0) { // collinear lines int j2 = j + numMatches; Line l2 = lines.get(j2); numMatches++; if (l2.flip) numFlipped++; else numNotFlipped++; } // ========================================= // ==== MOVE THE LINE ====================== // ========================================= above -= numNotFlipped; below -= numFlipped; // ========================================= // ==== DO THE MATH ======================== // ========================================= for (int k = 0; k < numFlipped; ++k) { l = lines.get(j + k); // current line int numCollinearToRemoved = numNotFlipped + k; double chance1 = etienne[above + numCollinearToRemoved]; double chance2 = etienne[below + numCollinearToRemoved]; double len = Math.sqrt(l.dir.magSquared()); ans += len * (chance1 + chance2); } // ========================================= // ==== MOVE THE LINE ONCE MORE ============ // ========================================= below += numNotFlipped; above += numFlipped; j += numMatches; } } ans /= 100; double circumph = D * Math.PI; pw.println(ans + circumph); pw.close(); } static class Point { long x, y; public Point(long x, long y) { this.x = x; this.y = y; } Point minus(Point other) { return new Point(x - other.x, y - other.y); } Point add(Point other) { return new Point(x + other.x, y + other.y); } Point mult(long s) { return new Point(s * x, s * y); } long dot(Point other) { return x * other.x + y * other.y; } long cross(Point other) { return x * other.y - y * other.x; } long magSquared() { return x * x + y * y; } } static class Line { Point dir; boolean flip; public Line(Point base, Point p) { if (p.y < base.y || (p.y == base.y && p.x < base.x)) { p = p.minus(base); this.dir = p.mult(-1); this.flip = true; } else { p = p.minus(base); this.dir = p; this.flip = false; } } public static int compare(Line a, Line b) { long c = a.dir.cross(b.dir); if (c == 0) { // collinear if (a.flip && !b.flip) return -1; // a comes first else if (b.flip && !a.flip) return 1; // b comes first; else if ((a.dir.magSquared() < b.dir.magSquared()) ^ a.flip) return -1; // a comes first else return 1; // b comes first } if (c < 0) return 1; // a comes before b else return -1; // a comes after a } } /* * Fast Reader */ static class FastReader { BufferedReader br; StringTokenizer st; public FastReader() { br = new BufferedReader(new InputStreamReader(System.in)); } String next() { while (st == null || !st.hasMoreElements()) { try { st = new StringTokenizer(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } return st.nextToken(); } int nextInt() { return Integer.parseInt(next()); } long nextLong() { return Long.parseLong(next()); } double nextDouble() { return Double.parseDouble(next()); } String nextLine() { String str = ""; try { str = br.readLine(); } catch (IOException e) { e.printStackTrace(); } st = null; return str; } } }