本题要注意的几个点,阶乘数是从0开始的,0的阶乘和1的阶乘都是1,所以集合里有两个1,还好输入的n比较小,只有1000000,因此集合元素只有1到9的阶乘,把里面所有和的可能遍历一下放到list里,根据输入来查找就行了。。话说这种算法好搓
#include<stdio.h>
#include<stdlib.h>
struct IntList
{
int *array;
int capacity;
int total;
};
typedef struct IntList *listptr;
listptr newList(int capacity)
{
listptr p = malloc(sizeof(struct IntList));
p->total = 0;
p->capacity = capacity;
p->array = malloc(capacity * sizeof(int));
return p;
}
void addInt(int num, listptr p)
{
if (p->total == p->capacity)
{
p->capacity *= 2;
int *newArray = realloc(p->array, (sizeof(int)) * p->capacity);
p->array = newArray;
}
int *array = p->array;
*(array + p->total) = num;
p->total++;
}
void freeList(listptr p)
{
free(p->array);
free(p);
}
int factorials(int n)
{
int r = 1, i;
for (i = 1; i <= n; i++)
r *= i;
return r;
}
int main()
{
listptr p = newList(1100);
addInt(1, p);
int i;
for (i = 1; i < 10; i++)
{
int total = p->total, j;
int num = factorials(i);
addInt(num, p);
for (j = 0; j < total; j++)
{
addInt(num + *(p->array + j), p);
}
}
int n, flag;
while (scanf("%d", &n), n >= 0)
{
flag = 0;
for (i = 0; i < p->total; i++)
if (*(p->array + i) == n)
{
flag = 1;
break;
}
printf(flag ? "YES\n" : "NO\n");
}
return 0;
}