这题我开始想暴算。。然后发现。。
1000!太大连double都会爆。。
//暴力片段
long long int jiecheng(int a)
{
if(a==0) return 1;
else
{
array[a]=a*jiecheng(a-1);
return array[a];
}
}
int zuheshu(int m,int n)
{
return (int)(jiecheng(m)/(jiecheng(n)*jiecheng(m-n)));
}
然后我想试试优化下算法,把递推算阶乘和组合数放到一起算,然并卵,C100 50就是10的299次方了。。。下面是当时的优化片段
double zuheshu(int m,int n)
{
if(m==x-y+1) return m*1.0/n;
else if(n==1) return (1.0*m)*zuheshu(m-1,1);
else return (m*1.0/n)*zuheshu(m-1,n-1);
}
然后我实在没办法了。。就试了试找规律,然后发现。。卧槽水题
末尾的零每多一个,就说明它乘了2,也就是说要想知道组合数的末尾有几个零,就是等于求这个组合数能有多少个是2的因子,然后弄个函数算因子就行了,就是我下面写的totwo函数。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
totwo(int a)
{
int sum=0,num;
for(int i=a;i>=1;i--)
{
int x=i;
num=0;
while(x%2!=1)
{
num++;
x=x/2;
}
sum+=num;
}
//cout<<sum<<endl;
return sum;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int m,n;
cin>>m>>n;
cout<<totwo(m)-totwo(n)-totwo(m-n)<<endl;
}
return 0;
}
总结:
多做题,多写解题报告。