链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1316
题意:
已知C(m,n) = m!/(n!(m-n)!),输入整数p, q, r, s(p≥q,r≥s,p,q,r,s≤10000),计算C(p,q)/C(r,s)。
输出保证不超过1e8,保留5位小数。
分析:
首先,求出10000以内的所有素数prime,然后用数组e表示当前结果的唯一分解式中各个素数的指数。
例如,e={1,0,2,0,0,0,…}表示21*52=50。具体实现见代码。
代码:
1 import java.io.*; 2 import java.util.*; 3 4 public class Main { 5 static int e[]; 6 static ArrayList<Integer> prime = new ArrayList<Integer>(); 7 8 static void getPrimeNumber(int up) { // 获取素数 9 boolean isp[] = new boolean[up+5]; 10 Arrays.fill(isp, true); 11 int u = (int)Math.sqrt(up + 0.5); 12 for(int t = 2; t <= u; t++) if(isp[t]) { 13 for(int i = t * t; i <= up; i += t) isp[i] = false; 14 } 15 for(int i = 2; i <= up; i++) if(isp[i]) prime.add(i); 16 } 17 18 static void addInteger(int n, int d) { // 乘以或除以n. d=1表示乘,d=-1表示除 19 for(int i = 0; i < prime.size(); i++) { 20 while(n % prime.get(i) == 0) { 21 n /= prime.get(i); 22 e[i] += d; 23 } 24 if(n == 1) break; 25 } 26 } 27 28 static void addFactorial(int n, int d) { // 把结果乘以(n!)的d次方 29 for(int i = 1; i <= n; i++) addInteger(i, d); 30 } 31 32 public static void main(String args[]) { 33 Scanner cin = new Scanner(new BufferedInputStream(System.in)); 34 getPrimeNumber(10000); 35 e = new int[prime.size()]; 36 37 while(cin.hasNext()) { 38 int p = cin.nextInt(); 39 int q = cin.nextInt(); 40 int r = cin.nextInt(); 41 int s = cin.nextInt(); 42 43 Arrays.fill(e, 0); 44 addFactorial(p, 1); 45 addFactorial(q, -1); 46 addFactorial(p-q, -1); 47 addFactorial(r, -1); 48 addFactorial(s, 1); 49 addFactorial(r-s, 1); 50 double ans = 1; 51 for(int i = 0; i < prime.size(); i++) 52 ans *= Math.pow(prime.get(i), e[i]); 53 System.out.printf("%.5f ", ans); 54 } 55 cin.close(); 56 } 57 }