题目链接
题目
我们知道有一种神奇的排序方法叫做猴子排序,就是把待排序的数字写在卡片上,然后让猴子把卡片扔在空中,等落下的时候观察这些卡片是否从左到右已经排序完成(我们认为不会发生卡片落地后叠在一起的情况)如果有序则排序完成,否则让猴子再扔一遍,直到卡片有序,那么问题来了,给你N个卡片,每个卡片上写着一个大写字母,请问猴子第一次扔这些卡片就按字典序排序完成的概率有多大?
输入描述:
第一行是一个整数N(1< N <100)表示给猴子N张卡片,接下来是一个长度为N的字符串,代表这些卡片上所写的字母。
输出描述:
输出一行,表示猴子排序第一次就成功的概率(用分子为1的分数表示)。
示例1
输入
7
SCIENCE
输出
1/1260
分析
扔N张卡片,次序有N!种可能。设字符A的重复次数为x,则有x!种同一排序,其他字符同理计算。根据乘法原理,总的重复次数有sum=x1!* x2!* x3!*…xk!。答案就是sum/N!。
N最大有100,64位无法存下,需要用高精度算法。这里,直接用java的BigInteger包实现。
AC代码
import java.math.BigInteger;
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner cin=new Scanner(System.in);
int n;
n=cin.nextInt();
BigInteger ans;
String s;
s=cin.next();
int[] a=new int[30];
int len=s.length();
for(int i=0;i<len;i++)
a[s.charAt(i)-'A']++;
ans=BigInteger.ONE;
for(int i=1;i<=n;i++)
ans=ans.multiply(BigInteger.valueOf(i));
for(int i=0;i<26;i++)
if(a[i]>0)
{
while(a[i]>0)
{
ans=ans.divide(BigInteger.valueOf(a[i]));
a[i]--;
}
}
System.out.println("1/"+ans);
}
}