http://www.elijahqi.win/archives/1027
背景
描述
1.组合数
(zero.cpp/c/pas)
时间限制:1s
内存限制:256MB
【问题描述】
从m个不同元素中,任取n(n≤m)个元素并成一组,叫做从m个不同元素中取出n个元素的一个组合;从m个不同元素中取出n(n≤m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数,记作C(m,n)。
你的任务是:计算C(m,n)末尾有几个0。如C(10,1)=10,末位有一个0。
【输入】
输入文件名为zero.in。
第一行一个数T(<=1000),表示数据组数
对于每一组数据:输入两个数,m和n
【输出】
输出文件名为zero.out。
对于每组数据输出一行,包含一个数,表示C(m,n)末尾有几个0
【输入输出样例】
zero.in
zero.out
3
10 1
11 7
20 4
1
1
0
【数据说明】
对于30%的数据,1<=m<=20;
对于70%的数据,1<=m<=1000
对于100%的数据,1<=m<=1000000
#include<cstdio>
#include<algorithm>
#define N 1100000
using namespace std;
inline int read(){
int x=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x;
}
struct node{
long long f2,f5;
}pre[N],ans;
int T,n,m;
int main(){
//freopen("zero.in","r",stdin);
//freopen("zero.out","w",stdout);
for (int i=1;i<=1000000;++i){
int x=i;
while (x){
bool flag=false;
if (x%5==0) pre[i].f5++,x/=5,flag=true;
if (x%2==0) pre[i].f2++,x/=2,flag=true;
if (flag==false) break;
}
pre[i].f2+=pre[i-1].f2;pre[i].f5+=pre[i-1].f5;
}
T=read();
while (T--){
n=read();m=read();ans.f2=0;ans.f5=0;
ans.f2=pre[n].f2-pre[n-m].f2;ans.f5=pre[n].f5-pre[n-m].f5;
ans.f2-=pre[m].f2;ans.f5-=pre[m].f5;
printf("%lld\n",min(ans.f2,ans.f5)<0?0:min(ans.f2,ans.f5));
}
return 0;
}