UVa10375:选择与除法(唯一分解定理)
The binomial coefficient C(m,n) is defined as

Given four natural numbers p, q, r, and s, compute the the result of dividing C(p,q) by C(r,s).
这是二次项系数,现在给出p,q,r,s,计算C(p,q)除以C(r,s)的结果
Input
Input consists of a sequence of lines. Each line contains four non-negative integer numbers giving values for p, q, r, and s, respectively, separated by a single space. All the numbers will be smaller than 10,000 with p ≥ q and r ≥ s.
输入:包含多组数据,pqrs均小于10000的非负整数。
Output
For each line of input, print a single line containing a real number with 5 digits of precision in the fraction, giving the number as described above. You may assume the result is not greater than 100,000,000.
输出:每行输出除法的结果保留小数点后5位结果,结果保证不超过一亿。
Sample Input
10 5 14 9
93 45 84 59
145 95 143 92
995 487 996 488
2000 1000 1999 999
9998 4999 9996 4998
Sample Output
0.12587
505606.46055
1.28223
0.48996
2.00000
3.99960
思路:指数级的乘法结果太大,运用一些约分的方法防爆。
方法一:
唯一分解定理以前介绍过,大意就是每个数都可以唯一地分解为一堆质数的幂的乘积,如90 = 2 * 3² * 5.其中2和5是一次幂,3是二次幂。
这样我们回到题目数据,显然很多时候我们把分子分母都分解以后会发现能约掉很多质数的幂,这样的话可以采取这样一种策略:用一个数组记录每个质数的幂指数,如果是分子的话就加,是分母的话就减,免去了反复的无用乘除法。当把分子分母们都处理完以后,约分后的分子分母就是答案的分数形式了,此时再求出结果即可。
先把10000以内的素数都记录下来。
然后对每个数据来说,p、s、r-s是分子,q、p-q、r是分母。
接着把这六个数分别代入修改函数,修改素数幂指数数组的值,对于此数组,以90为例,应为every_count={1,2,1,0,0,0,……}。
详见代码,220ms:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std; int p, q, r, s, primes_size/*10000以内素数个数*/;
int all_primes[];//10000以内素数的按顺序具体记录
int every_count[];//每个素数幂指数的记录数组
bool is_composite[];//判定是否为合数 void modify_count(int a, int d)
{
for (int i = ; a > && i < primes_size; i++)
while (a % all_primes[i] == )
{
every_count[i] += d;//1与-1的传入使得修改写起来简便
a /= all_primes[i];
}
} void add_factorial(int n, int d)
{
for (int i = ; i <= n; i++)//n!
modify_count(i, d);//修改every_count数组
} void get_primes()
{
for (int i = ; i < ; i++)
if (!is_composite[i])
{
for (int j = i*i; j < ; j += i)
is_composite[j] = true;
all_primes[primes_size++] = i;
}
} int main()
{
get_primes();//埃氏筛素数 while (cin >> p >> q >> r >> s)
{
memset(every_count, , sizeof(every_count)); //进行6次分解,1与-1的用途见函数内部
add_factorial(p, );
add_factorial(p-q, -);
add_factorial(q, -); add_factorial(r, -);
add_factorial(r-s, );
add_factorial(s, ); //最后利用素数数组一次性求得答案
double ans = 1.0;
for (int i = ; i < primes_size; i++)
ans *= pow(all_primes[i], every_count[i]); cout << fixed << setprecision() << ans << endl;
} return ;
}
方法二:
也是约分的方式,数学知识降维打击。想必大家都知道上边下边的感叹号是可以约下去一堆的。这里有个知识是,如果你把m!约下去n!,剩下的是n+1~m,数字个数与1~m-n+1相等。也就是可以进行一一对应的double结果乘除。同理约下去(m-n)!也是一样的。
见代码即懂,0ms:
#include <cstdio> int main()
{
int p, q, r, s;
while (~scanf("%d%d%d%d", &p, &q, &r, &s))
{
double ans = 1.0;
for (int i = , j = p-q+, x = , y = r-s+; i <= q || x <= s;)
{
if (i <= q) ans *= (double)(j++)/(i++); if (x <= s) ans *= (double)(x++)/(y++);
}
printf("%.5lf\n", ans);
}
}
最后,虽然方法二严重打击了方法一的信心与自尊心,不过方法一的思想还是很不错的,值得学习。
UVa10375:选择与除法(唯一分解定理)的更多相关文章
- Uva 10375 选择与除法 唯一分解定理
		题目链接:https://vjudge.net/contest/156903#problem/E 题意:已知 求:C(p,q)/C(r,s) 其中p,q,r,s都是10^4,硬算是肯定超数据类型的. ... 
- uva10375 Choose and Divide(唯一分解定理)
		uva10375 Choose and Divide(唯一分解定理) 题意: 已知C(m,n)=m! / (n!*(m-n!)),输入整数p,q,r,s(p>=q,r>=s,p,q,r,s ... 
- UVA10375 选择与除法 Choose and divide 题解
		题目链接: https://www.luogu.org/problemnew/show/UVA10375 分析: 这道题可以用唯一分解定理来做. 什么是唯一分解定理?百度即可,这里也简介一下. 对于任 ... 
- Choose and divide(唯一分解定理)
		首先说一下什么是唯一分解定理 唯一分解定理:任何一个大于1的自然数N,如果N不是质数,那么N可以分解成有限个素数的乘积:例:N=(p1^a1)*(p2^a2)*(p3^a3)......其中p1< ... 
- NOIP2009Hankson 的趣味题[唯一分解定理|暴力]
		题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson.现 在,刚刚放学回家的 Hankson 正在思考一个有趣的问题. 今天在课堂上,老师讲 ... 
- POJ - 1845   G - Sumdiv  (唯一分解定理)
		Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S m ... 
- HDU 6069 Counting Divisors(唯一分解定理+因子数)
		http://acm.hdu.edu.cn/showproblem.php?pid=6069 题意: 思路: 根据唯一分解定理,$n={a_{1}}^{p1}*{a2_{}}^{p2}...*{a_{ ... 
- Irrelevant Elements UVA - 1635 二项式定理+组合数公式+素数筛+唯一分解定理
		/** 题目:Irrelevant Elements UVA - 1635 链接:https://vjudge.net/problem/UVA-1635 题意:給定n,m;題意抽象成(a+b)^(n- ... 
- UVA - 10375 Choose and divide[唯一分解定理]
		UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS Memory Limit: 65536K Total Subm ... 
随机推荐
- charles刷分微信跳一跳小程序对https的理解
			以前以为只要安装了https 客户端与服务端的数据会被加密就安全了 事实上 只要任意一款抓包工具 并伪造证书 就可以解密这个被所谓https加密的数据 如 可以下载charles的根证书 作为伪 ... 
- [zjoi2003]密码机
			一台密码机按照以下的方式产生密码:首先往机器中输入一系列数,然后取出其中一部分数,将它们异或以后得到一个新数作为密码.现在请你模拟这样一台密码机的运行情况,用户通过输入控制命令来产生密码.密码机中存放 ... 
- Codeforces Round #394 (Div. 2) B. Dasha and friends —— 暴力 or 最小表示法
			题目链接:http://codeforces.com/contest/761/problem/B B. Dasha and friends time limit per test 2 seconds ... 
- oracle添加表注释和表字段注释
			创建Oracle数据库表时加上注释 CREATE TABLE t1( id varchar2(32) primary key,name VARCHAR2(8) NOT NULL, age numbe ... 
- dtd文件中写的引用实体被xml文件引用后无法在浏览器中显示的问题
			解决方案:把dtd文件由被xml文件外部引用改成被xml文件内部引用. 例子: 1.xml文件: <?xml version="1.0" encoding="UTF ... 
- hdu 1040 As Easy As A+B(排序)
			题意:裸排序 思路:排序 #include<iostream> #include<stdio.h> #include<algorithm> using namesp ... 
- C++之pair与make_pair
			std::pair主要的作用是将两个数据组合成一个数据,两个数据可以是同一类型或者不同类型. 例如std::pair<int,float> 或者 std::pair<double,d ... 
- 转:ubuntu下安装ssh服务
			本文内容来自 http://www.cnblogs.com/chen1987lei/archive/2010/12/02/1894768.html ========================= ... 
- 【旧文章搬运】NtGlobalFlags
			原文发表于百度空间,2010-08-06========================================================================== - NtG ... 
- office2016出现 此功能看似已中断 并需要修复
