import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ /** * * @author cteam014 */ public class Northwest { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); public void solve() throws Exception { String line; while ((line = reader.readLine()) != null) { long N = Integer.parseInt(line); //int[] towns = new int[N*2]; HashMap indicesNW = new HashMap(); HashMap indicesNE = new HashMap(); ArrayList diagonalsNW = new ArrayList<>(10000); ArrayList diagonalsNE = new ArrayList<>(10000); for (int i = 0; i < N; i++) { line = reader.readLine(); String[] a = line.split(" "); int x = Integer.parseInt(a[0]); int y = Integer.parseInt(a[1]); long NWdiagonal = x + y; long NEdiagonal = y - x; if (indicesNW.containsKey(NWdiagonal)) { int index = indicesNW.get(NWdiagonal); diagonalsNW.set(index, diagonalsNW.get(index) + 1); } else { indicesNW.put(NWdiagonal, diagonalsNW.size()); diagonalsNW.add(1); } if (indicesNE.containsKey(NEdiagonal)) { int index = indicesNE.get(NEdiagonal); diagonalsNE.set(index, diagonalsNE.get(index) + 1); } else { indicesNE.put(NEdiagonal, diagonalsNE.size()); diagonalsNE.add(1); } } long numOfDiagonalPairs = 0; for (int i = 0; i < diagonalsNW.size(); i++) { long diagonal = diagonalsNW.get(i); numOfDiagonalPairs += diagonal * (diagonal - 1); } for (int i = 0; i < diagonalsNE.size(); i++) { long diagonal = diagonalsNE.get(i); numOfDiagonalPairs += diagonal * (diagonal - 1); } float probability = ((float) numOfDiagonalPairs) / (N*N); System.out.println(probability); } } public static void main(String[] args) throws Exception { new Northwest().solve(); //long a = 100000; //System.out.println(a*a); } }