题目链接:
点击打开链接
题中所求是C(
m,
n)转换为二进制数后,其末尾有多少个0,我们可以利用公式C(
m,
n) =
m!/((
m -
n)!
n!) 将C(
m,
n) 直接求出来,然后将其对2取余,如果余数为0,就说明它的二进制数有一个0,然后将其除2再对2取余,如此循环直到余数不为0,考虑到C(
m,
n) 可能很大,我们可以使用Java中的BigInteger类来实现:
import java.util.*;
import java.math.BigInteger;
import java.text.DecimalFormat;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(System.in);
int T = cin.nextInt();
while(T!=0)
{
T--;
int m = cin.nextInt();
int n = cin.nextInt();
BigInteger s1 = BigInteger.valueOf(1);
BigInteger s2 = BigInteger.valueOf(1);
BigInteger s3 = BigInteger.valueOf(1);
for(int i=1;i<=m;i++)
{
BigInteger x = BigInteger.valueOf(i);
s1 = s1.multiply(x);
}
for(int i=1;i<=m-n;i++)
{
BigInteger x = BigInteger.valueOf(i);
s2 = s2.multiply(x);
}
for(int i=1;i<=n;i++)
{
BigInteger x = BigInteger.valueOf(i);
s3 = s3.multiply(x);
}
BigInteger sum = s1.divide(s2.multiply(s3));
int result = 0;
while(sum.remainder(BigInteger.valueOf(2))==BigInteger.ZERO)
{
result++;
sum = sum.divide(BigInteger.valueOf(2));
}
System.out.println(result);
}
}
}
当然我们可以不必将C(
m,
n) 完全算出来,因为C(
m,
n) =
m!/((
m -
n)!
n!) ,就可以将C(
m,
n) 分为m!、(m-n)!、n!三部分,K!又可以看成K个数,可以通过循环来对这K个数取余除2直到不能再取,此时就不会出现大整数了:
import java.util.*;
import java.math.BigInteger;
import java.text.DecimalFormat;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
class C
{
public int CC(int m)
{
int sum = 0;
for(int i=1;i<=m;i++)
{
int x = i;
while(x%2==0)
{
sum++;
x /= 2;
}
}
return sum;
}
}
Scanner cin = new Scanner(System.in);
int T = cin.nextInt();
while(T!=0)
{
T--;
int m = cin.nextInt();
int n = cin.nextInt();
C t = new C();
int s1 = t.CC(m);
int s2 = t.CC(m-n);
int s3 = t.CC(n);
System.out.println(s1-s2-s3);
}
}
}
当然,用C++实现更简单,更快:
#include <cstdio>
#include <iostream>
using namespace std;
int C(int m)
{
int sum = 0;
for(int i=2;i<=m;i++)
{
int x = i;
while(x%2==0)
{
sum++;
x /= 2;
}
}
return sum;
}
int main(void)
{
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>m>>n;
cout<<C(m)-C(m-n)-C(n)<<endl;
}
}