Problem Description
LB是个十分喜欢钻研的人,对什么事都要搞明白。有一天他学习到了阶乘,他十分喜欢,所以他在想一个问题。如果给定一个数n,求n!能不能被2016整除。LB算了好久都没有算出来,所以他向你求助,你能不能帮他解决这个问题呢?
Input
第一行只包含一个整数T(T≤1000),表示测试用例的个数。
对于每个测试用例,第一行只包含一个整数N(0≤N≤10000),N如描述所示。
对于每个测试用例,第一行只包含一个整数N(0≤N≤10000),N如描述所示。
Output
对于每个测试用例,输出一行,如果N!能被2016整除输出"YES"(不带引号),如果不能输出"NO"(不带引号)。
Sample Input
1 2016
Sample Output
YES
Author
当然这里并没有那么麻烦
#include<stdio.h>
#include<string.h>
struct node
{
long p;
long n;
node()
{
n=0;
}
};
long prime[50000];
bool flag[50000];
node stc[1000];
long num1=0,num2;
void init()
{
unsigned long i,j;
memset(flag,0,sizeof(flag));
for(i=2; i<50000; i++)
{
if(!flag[i])
{
prime[num1++]=i;
for(j=i*i; j<50000; j=j+i)
flag[j]=true;
}
}
}
void devide(long m)
{
long i;
num2=0;
for(i=0; prime[i]*prime[i]<=m; i++)
{
if(m%prime[i]==0)
{
stc[num2].p=prime[i];
stc[num2].n++;
m=m/prime[i];
while(m%prime[i]==0)
{
stc[num2].n++;
m=m/prime[i];
}
num2++;
}
if(m==1)
break;
}
if(m>1)
{
stc[num2].p=m;
stc[num2].n++;
num2++;
}
}
bool judge(long n,long m)
{
long i,sum,temp;
for(i=num2-1; i>=0; i--)
{
sum=0;
temp=stc[i].p;
while(n>=temp)
{
sum=sum+n/temp;
temp=temp*stc[i].p;
}
if(sum<stc[i].n)
return false;
}
return true;
}
int main()
{
long n,m,i;
init();
int t;
while(~scanf("%d",&t))
{
while(t--)
{
scanf("%d",&n);
m=2016;
for(i=0; i<1000; i++)
stc[i].n=0;
if(n<=1&&m>1)
{
puts("NO");
continue;
}
if(m==0)
{
puts("NO");
continue;
}
if(n>=m)
{
puts("YES");
continue;
}
devide(m);
if(judge(n,m))
{
puts("YES");
}
else
{
puts("NO");
}
}
}
return 0;
}