先放上官方題解:
說一下對下面式子的理解:
其中,
表示在二維上兩直線相交的所有方案數,x,y分別表示水平線段的行標號與豎直線段的列標號,對其進行枚舉, 當x=x0,y=y0時,兩線段只可能相交於點(x0,y0);此時經過點(x0,y0)的豎直線段方案數爲:(x0+1)*(N-x0)-1. (求法:選取豎直線段的上下端點,上端點的選法有x0+1種,下端點的選法有N-x0種,再減去上下端點均爲(x0,y0)這一種)
水平線段方案數同理;
剩下的部分就是 ,這一部分是二維平面上兩直線相對位置的所有方案數,作爲分母。
/*
另外,兩線段在同一平面的概率爲1/N^(D-2) 的求法:一線斷位置確定後,另一線段所有位置的方案數爲:N^D,因爲在同一平面的兩線段向量最多隻有兩個維度上的分量是對應不相等的,故兩線段在相同平面的方案數爲N^2;相除即得。
*/
代碼:
import java.util.*;
import java.math.*;
public class Main{
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int D;
BigInteger up,down,_gcd,N;//N也要初始化爲BigInteger,否則會溢出
while(input.hasNext()){
N=input.nextBigInteger();
D=input.nextInt();
up=new BigInteger(D*(D-1)+"");
up=up.multiply(N.add(BigInteger.valueOf(4)).pow(2));
down=new BigInteger(18+"");
for(int i=1;i<=D;++i){
down=down.multiply(N);
}
_gcd=up.gcd(down);
up=up.divide(_gcd);
down=down.divide(_gcd);
if(down.equals(BigInteger.ONE)){
System.out.println(up);
}
else{
System.out.println(up+"/"+down);
}
}
}
}