描述
给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3!,如果是,则输出Yes,否则输出No;
输入
第一行有一个整数
0<m<100
,表示有m组测试数据;
每组测试数据有一个正整数n<1000000;
输出
如果符合条件,输出Yes,否则输出No;
样例输入
2
9
10
样例输出
Yes
No
思路:贪心算法(注意输出时大小写问题)
1!=1
2!=2
3!=2*3
4!=2*3*4
5!=2*3*4*5
很显然 , (1! + 2!+3! + 4!) < 5!
所以可以得出结论,对于任意n! , 他的值恒大于前n-1个数的阶乘的和
即
n!>∑n−11(i!)
1. 也就是说,n! 不可能有前面n-1个数的阶乘代替
对于a ,如果
n!<=a<(n+1)!,那么a一定包括n!,原因:a=b!+c!+d!,令a=n!+k,令f为大于n的任意数,则f!>a,所以也不能够取f,如果a不取n!,由于n!不能够被前面n−1个数的阶乘代替,所以一定有
a>∑n−11(i!)+k
, 所以必须取n!
#include<stdio.h>
int jiecheng(int* a ,int m);
int main()
{
int m=0,n=0;
int i=0,j=0;
scanf("%d",&m);
int k=0,l=0;
int a[100]={1}; //a[i] 表示前i个数的阶乘
l=jiecheng(a,1000000);//计算k,使得k!<1000000<(k+1)!
for(i=1;i<=m;i++)
{
scanf("%d",&n);
//n=i;
k=l;
while(n>0 && k>0)
{
for(j=1;j<=k;j++)
{
if(a[j]<=n && (a[j+1]>n || j==k))
{
n=n-a[j];
//printf("%d ",j);
k=j-1;
break;
}
}
}
//printf("%d ",i);
if(n>0)
{
printf("No\n");
}
else
{
printf("Yes\n");
}
}
return 0;
}
int jiecheng(int* a , int m)
{
int i=1;
a[1]=1;
for(i=2;;i++)
{
if(a[i-1]>m)
{
break;
}
a[i]=a[i-1]*i;
}
return i-1;
}