读书人

求教关于“组合数末尾的0”的有关问题

发布时间: 2012-12-16 12:02:32 作者: rapoo

求教关于“组合数末尾的0”的问题 帮我改下代码谢谢了~
问题如下:
Description
从m个不同元素中取出n (n ≤ m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数。组合数的计算公式如下:
C(m, n) = m!/((m - n)!n!)

现在请问,如果将组合数C(m, n)写成二进制数,请问转这个二进制数末尾有多少个零。

Input
第一行是测试样例的个数T,接下来是T个测试样例,每个测试样例占一行,有两个数,依次是m和n,其中m ≤ n ≤ 1000。

Output
分别输出每一个组合数转换成二进制数后末尾零的数量。
Sample Input
2
4 2
1000 500
Sample Output
1
6

***********代码如下*************************

#include<stdio.h>
int main(){
int i,n,v,a,b,j,c,z,k,y,r,l,count;int temp[10000];
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d %d",&a,&b);c=a-b;int s=1;int x=1;
for(z=a;z>0;z--) //求组合数
s=s*z;
for(j=b;j>0;j--)
x=x*j;
for(k=1;k<=c;k++)
c=c*k;
y=s/(x*c);
while(y>0) //把y转换成2进制
{r=y%2;
y=y/2;v=0;
temp[v]=r;
v=v+1;count=0;
for(l=0;l<=v;l++) //判断是不是0,是0就加1;
{if(temp[l]=='0')
count=count+1;
}printf("%d\n",count);}
}
return 0;
}

[最优解释]
话说LZ没学过组合数的化简公式么?

C(m,n)=P(m,n)/m!(m≤n,PS:貌似排列数也有记作A(m,n)的,但我们的习惯是记为P(m,n))
P(m,n)=n!/(n-m)!=n*(n-1)*...*(n-m+1)


#include<stdio.h>
#include<stdlib.h>

long long c(int,int);

int main()
{
int n=-1,n1,n2,count;
long long r;
register int i;

//输入数据组数
do
{
printf("Please input the count of groups of datas:");
fflush(stdin);
scanf("%d",&n);
}while(n<=0);

for(i=0;i<n;i++)
{
printf("Input datas:");
fflush(stdin);
scanf("%d %d",&n1,&n2);
n1=max(n1,0);
n2=max(n2,0);//确保输入非负

printf("c=%lld\n",(r=c(n1,n2)));

for(count=0;!(r&1);r>>=1,count++);//计算r的二进制尾部有几个0

printf("The number of zero at the end:%d\n",count);
}

system("pause");

return(0);
}

long long c(int m,int n)
{
int t;
register int i;
long long a=1,b=1;

if(n<m)
m^=n^=m^=n;//确保m≤n

for(i=n,t=n-m;i>t;i--)
a*=i;//a=(n-m+1)*(n-m)*...*n=P(m,n)

for(;m>1;m--)
b*=m;//b=m*(m-1)*...*1=m!

return(a/b);
}

PS:1000,500这组数据求不出是因为溢出了。long long对500!截断后为0,除数为0而导致程序错误。
[其他解释]
仅供参考。。
#include<iostream>

using namespace std;
int Num_Of_Zero(int Num)
{
int i=0;
for(int j = Num;j!=0;j/=2)
{
int temp = j%2;
if(temp == 0)
i++;
else
break;
}
return i;
}
int main()
{
int Num_M,Num_N,Num_Zero = 0;
cout<<"M,N(M>N):";
cin>>Num_M>>Num_N;
if(Num_M<Num_N)
{
cout<<"Error."<<endl;
system("pause");
return 0;
}

for(int i = Num_M-Num_N+1,k = 1;i<=Num_M;i++,k++)


{
Num_Zero += Num_Of_Zero(i);
Num_Zero -= Num_Of_Zero(k);
}
cout<<"共有"<<Num_Zero<<"个0。"<<endl;
system("pause");
return 0;
}


[其他解释]
难道就不知道数学方法么?直接求有多少个因子2不就行了?

读书人网 >C语言

热点推荐