题目大意:判断输入的整数能否表示成1个或者多个不相同的整数的阶乘的和,如果能,输出YES,否则输出NO,输入负数表示输入结束,输入数最多1000000.
解题思路:
1)设i<=n-1,有i!<=(n-1)!,就有0~n-1的阶乘和sum(i!)<=n(n-1)!=n!
2)所以i从大到小,如果i!<n,i!必须用来表示n,因为如果放弃了当前的i!,后面小于i的阶乘的和 <=i! <n(上面公式得出)
数(n-1)!之前的和小于n!,如果一个数大于n!,就一定包含n!相加,因为找不到任何阶乘的和能够大于n!(后面n之后阶乘的和比n!小),只要碰到
n!小于给定的数就相减,如果大于就跳到下一位,知道那个数剩下0,若不为0则输出NO*/
#include<cstdio>
#include<iostream>
using namespace std;
int n;
int arr[12];
int jisuanjiecheng(int n){
if(n == 0) return 1;
else if(n == 1) return 1;
else return n*jisuanjiecheng(n - 1);
}
int main(){
for(int i = 0; i <= 11; i++){
arr[i] = jisuanjiecheng(i);
//printf("%d\n", arr[i]);
}
while(scanf("%d", &n), n >= 0){
if(n == 0){
printf("NO\n");
continue;
}
int flag = 0;
for(int i = 11; i>= 0; i--){
if(arr[i] <= n) n = n - arr[i];
if(n == 0){
flag = 1;
break;
}
}
if(flag == 1) printf("YES\n");
else printf("NO\n");
}
return 0;
}