import java.io.*;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.*;

public class Mark128Faster {

    static MathContext PRECISION_LEVEL = MathContext.DECIMAL128;

    static BigDecimal[] etienne;
    public static void initEtienne(int N, int K)
    {
        BigDecimal bN = BigDecimal.valueOf(N);
        BigDecimal bK = BigDecimal.valueOf(K);
        BigDecimal bN1 = BigDecimal.valueOf(N-1);
        BigDecimal bK1 = BigDecimal.valueOf(K-1);
        etienne = new BigDecimal[2001];
        if (N == 1)
            etienne[0] = BigDecimal.ONE;
        else
            etienne[0] = bK.multiply(bK1, PRECISION_LEVEL).divide(bN.multiply(bN1, PRECISION_LEVEL), PRECISION_LEVEL);

        for (int i = 1; i < 2001; ++i)
        {
            if (N - K >= i && K >= 2)
            {
                // i: to remove
                BigDecimal bN2i = BigDecimal.valueOf(N-2-(i-1));
                BigDecimal bNKi = BigDecimal.valueOf(N-K-(i-1));

                etienne[i] = etienne[i-1].multiply(bNKi, PRECISION_LEVEL).divide(bN2i, PRECISION_LEVEL);
            }
            else
                etienne[i] = BigDecimal.ZERO;
        }
    }

    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);
        BigDecimal ans = BigDecimal.ZERO;

        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<Line> 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;

                    BigDecimal chance1 = etienne[above + numCollinearToRemoved];
                    BigDecimal chance2 = etienne[below + numCollinearToRemoved];
                    BigDecimal len = BigDecimal.valueOf(Math.sqrt(l.dir.magSquared()));
                    ans = ans.add(len.multiply(chance1.add(chance2)), PRECISION_LEVEL);
                }

                // =========================================
                // ==== MOVE THE LINE ONCE MORE ============
                // =========================================

                below += numNotFlipped;
                above += numFlipped;

                j += numMatches;
            }
        }

        ans = ans.divide(BigDecimal.valueOf(100), PRECISION_LEVEL);
        BigDecimal circumph = BigDecimal.valueOf(D).multiply(BigDecimal.valueOf(Math.PI));
        pw.println(ans.add(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;
        }
    }
}