时间限制:3000 ms | 内存限制:65535 KB
难度:3
- 描述
-
给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3!,如果是,则输出Yes,否则输出No;
- 输入
- 第一行有一个整数0<m<100,表示有m组测试数据;
每组测试数据有一个正整数n<1000000; - 输出
- 如果符合条件,输出Yes,否则输出No;
- 样例输入
-
2 9 10
- 样例输出
-
Yes No
方法1:贪心#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int fact[12]; void solve() { int n; scanf("%d",&n); for(int i=10;i>=1;i--) if(n>=fact[i]) n-=fact[i]; if(n==0) printf("Yes "); else printf("No "); } int main() { fact[1]=1; for(int i=2;i<=10;++i) fact[i]=fact[i-1]*i; int m; scanf("%d",&m); while(m--) solve(); } //贪心策略:每次从10!往下,若n>=fact[i],n-=fact[i] //x!>(x-1)!+(x-2)!+(x-3)!+...(1)!
方法2:10!已经超过n的最大值
那么只要枚举1!,2!,3!。。。。。10!中任意几个数的和,即枚举1~10的子集
可以用二进制法:
//二进制法枚举子集 void get_sub(int n,int s) { for(int i=0;i<n;++i) if(s&(1<<i)) ans+=fact[i]; } for(int i=0;i<(1<<n);i++) get_sub(n,i);