先放上官方题解:
说一下对下面式子的理解:
其中,
表示在二维上两直线相交的所有方案数,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);
}
}
}
}