poj 3219 解析: 求阶乘中某质因子个数的方法

一、求阶乘中某质因子个数的方法
求一个阶乘数中某因子的个数,常用的方法如下:(扩展,lucas定理是关于组合数模一个质因子p后的余数)
先看懂例子:9!中含有多少个2
9! = 9×8×7×6×5×4×3×2×1
= (8×6×4×2)×9×7×5×3×1,后面的9×7×5×3×1就是other;
= 2^4×(4×3×2×1)×other,2的倍数的4个数每个分出一个2来,就是 2^k×k!×other
所以,这里首先得到9/2= 4,有4个2;
然后再对(4×3×2×1)重复上述步骤:
(4321)=4×2×3×1 = 2^2×(2×1) ×3×1,又得到2个2;
再对(2×1)重复,得到1个2,所以,9!中有7个2的因子;
理论基础是这样的:求阶乘后某因子个数
给定两个数n,k,求n!分解质因数后因子k的个数。(这里考虑k是质数的情况,否则没意思)
n!=1
23……(n-2)(n-1)n
可以表示成所有和k倍数有关的数的乘积,与其它和k没有关系的数的乘积;也就是,比n小的数中有k、2k、…、一直到tk(一共有t个);
n!=(k
2k3ktk)other other是不含k因子的数的乘积,因为tk<=n,可以求出最大的t=n/k;
然后这t个数每一个提取一个k出来,就变成k^t×t!;
=k^t
(1
2*…*t)other
=k^t
t!*other     
从这个表达式中可以提取出t个k,然后按照相同的方法循环下去可以求出t!中因子k的个数。
每次求出k的个数的和就是n!中因子k的总个数。
基本程序如下:(求n!中k的个数)
int jc(int n,int k)
{
int sum=0;
while(n)
{
sum = sum + n/k;
n = n/k;//相当于前面讲的t,对t!重复
}
return sum;
}
二、本题的思路
组合数位N!/(K!(N-K)!)分别求出 N! K! (N-K)!中因子2的个数 如果N!中2的因子个数大于后两项的和,那么就是偶数,如果等于就为奇数。

#include
using namespace std;
int jc(int N)
{
int sum=0;
while(N)
{
sum=sum+N/2;
N=N/2;
}
return sum;
}
int n,m;
int main()
{
while(scanf("%d%d", &n, &m)!=EOF)
{
int a=jc(n);
int b=jc(m);
int c=jc(n-m);
if(a>b+c)
cout<<“0”<<endl;
else
cout<<“1”<<endl;
}
system(“pause”);
return 0;
}

三、3219题意
题目:二项式系数奇偶性的判定;
题意:判断组合数C(n,m)的奇偶性。C(n,m)= n!/(m!(n-m)!)。
输入: n 和 k (0 ≤ k ≤ n < 231, n > 0),直到不输入为止;
输出: C(n, k)除以2后的余数(0或1);

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值