组合数末尾的零
Description
从m个不同元素中取出n (n ≤ m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数。组合数的计算公式如下:
C(m, n) = m!/((m - n)!n!)
现在请问,如果将组合数C(m, n)写成二进制数,请问转这个二进制数末尾有多少个零。
Input
第一行是测试样例的个数T,接下来是T个测试样例,每个测试样例占一行,有两个数,依次是m和n,其中n ≤ m ≤ 1000。
Output
分别输出每一个组合数转换成二进制数后末尾零的数量。
Sample Input
24 21000 500
Sample Output
16
数很大不能计算出m的组合数,将组合数的分子分母中所有2的因子分离出来,那么相除的结果中剩余的2的因子,也就是组合数2的因子,即末尾0的个数(二进制数末尾添加一个零就等于对该数乘二)
- #include <iostream>
- using namespace std;
- int solve(int n)
- {
- int sum=0;
- for(int i=1;i<=n;i++)
- {
- int x=i;
- while(x)
- {
- if(x&1) break;
- sum++;
- x/=2;
- }
- }
- return sum;
- }
- int main()
- {
- int T,n,m;
- scanf("%d",&T);
- while(T--)
- {
- scanf("%d %d",&n,&m);
- printf("%d\n",solve(n)-solve(n-m)-solve(m));
- }
- return 0;
- }
- #include<iostream>
- using namespace std;
- int C(int m,int n)
- {
- int i,sum1=0,sum2=0,j;
- for(i=m,j=n;j>0;i--,j--)
- {
- int a=i;
- int b=j;
- while(a%2==0)
- {
- sum1++;
- a/=2;
- }
- while(b%2==0)
- {
- sum2++;
- b/=2;
- }
- }
- return sum1-sum2;
- }
- int main()
- {
- int T,m,n;
- cin>>T;
- while(T--)
- {
- cin>>m>>n;
- cout<<C(m,n)<<endl;
- }
- return 0;
- }