题目描述
有些数可以表示成若干个不同阶乘的和。例如,9=1!+2!+3!。小明对这些数很感兴趣,所以他给你一个正整数n,想让你告诉他这个数是否可以表示成若干个不同阶乘的和。
输入
输入包含多组测试数据。每组输入为一个非负整数n(n<=1000000),当n为负数时,输入结束。
输出
对于每组输入,如果n可以表示成若干个不同阶乘的和,则输出YES,否则输出NO。
样例输入
9
-1
样例输出
YES
分析:
由于
0 != 1
1 != 1
2 != 2
3 != 6
4 != 24
5 != 120
6 != 720
7 != 5040
8 != 40320
9 != 362880
10 != 3628800
容易看出,9的阶乘 < n < 10的阶乘
解题思路:
- 利用一个fac()函数,先将0 ~ 9的阶乘存储在一个nums数组中
- 接收输入的数字,若这个数为负数,则结束输入
- 若输入的数为正数:
①用输入的数从后往前依次减去nums数组中的数
②若差值大于0,则继续执行①,差值小于0,则不执行作差操作 - 若可以使输入的数最后变为0,则说明其可以表示为若干个不同的数阶乘的和
AC代码如下:
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int nums[15];
//递归求阶乘
int fac(int n)
{
if (n == 0 || n == 1) return 1;
return n * fac(n - 1);
}
int main()
{
int n;
//将0 ~ 9阶乘的结果放到数组中
for (int i = 0;i <= 9;i++) nums[i] = fac(i);
while (cin >> n)
{
if (n < 0) break;//输入负数则结束输入
if (n == 0)
{
printf("NO\n");//0的阶乘是1,故0不能表示成其他数阶乘的和
continue;//继续下一组输入
}
for (int j = 9;j >= 0;j--)
{
if (n - nums[j] >= 0) n -= nums[j];
if (n == 0)
{
printf("YES\n");
break;
}
}
if (n != 0) printf("NO\n");//循环结束n仍大于0则说明不能表示为阶乘的和
}
return 0;
}
while循环中的for循环里有两个if语句,若将其调换位置则不能AC,有大佬看见希望能给予本菜鸟一些指点。