A Daily Topic # 7 阶乘的和(二进制/枚举)

A Daily Topic # 7

阶乘的和

给定一个非负整数 nn,请你判断是否存在一些整数 xi,能够使得 n=∑1≤i≤t xi,其中 t≥1,xi≥0,xi=xj iff i=j。

iff 表示当且仅当。

输入格式

输入包含多组测试数据。

每组数据占一行,包含一个非负整数 n。

最后一行是一个负数,表示输入结束,无需处理。

输出格式

每组数据输出一行结果,如果 n 能表示为若干数的阶乘之和,则输出 YES,否则输出 NO

数据范围

0≤n≤1e6,
每组输入最多包含 100 组数据。

输入样例:

9
-1

输出样例:

YES

+++

思路: 10! = 3628800 > 1e6 所以我们可选择的阶乘在0!到9!之间一共十种选择,我们可以二进制枚举每种方法存到哈希表中,然后查询n是否存在即可。

code
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_set>

using namespace std;

int f[10];
int n;
unordered_set<int> s;

int main()
{
    for (int i = 0; i <= 9; i ++ )
    {
        f[i] = 1;
        for (int j = i; j; j -- ) f[i] *= j;
    }
    
    //for (int i = 0; i <= 9; i ++ ) cout << f[i] << ' ';
    
    for (int i = 1; i < 1 << 10; i ++ )
    {
        int res = 0;
        for (int j = 0; j < 10; j ++ )
            if (i >> j & 1) res += f[j];
        
        s.insert(res);
    }
    
    while (cin >> n, n >= 0)
        if (s.count(n)) puts("YES");
        else puts("NO");
    
    return 0;
}
posted @ 2021-05-16 22:25  sunnyday0725  阅读(52)  评论(0编辑  收藏  举报