概述
题目描述
给定一个非负整数 n,请你判断是否存在一些整数 xi,能够使得 n=∑1≤i≤txi!,其中 t≥1,xi≥0,xi=xj iff i=j。
iff 表示当且仅当。
输入格式
输入包含多组测试数据。
每组数据占一行,包含一个非负整数 n。
最后一行是一个负数,表示输入结束,无需处理。
输出格式
每组数据输出一行结果,如果 n 能表示为若干数的阶乘之和,则输出 YES,否则输出 NO。
数据范围
0≤n≤106,
每组输入最多包含 100 组数据。
样例
输入样例:
9
-1
输出样例:
YES
样例
输入样例:
9
-1
输出样例:
YES
思路一:
dfs暴力枚举
时间复杂度
参考文献
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_set>
using namespace std;
const int N = 1e5+10;
int n;
int sum;
bool flag;
int a[10] = {1,1,2,6,24,120,720,5040,40320,362880};
void dfs(int sum,int u)
{
if(u==10)
{
if(n==sum)flag=true;
return ;
}
dfs(sum+a[u],u+1);
dfs(sum,u+1);
}
int main()
{
while(cin>>n,n>=0)
{
if(n==0)
{
cout << "NO"<<'n';
continue;
}
dfs(0,0);
if(flag)puts("YES");
else puts("NO");
flag=false;
}
return 0;
}
Java代码
import java.util.*;
public class Main{
static int[] p = new int[10];
static int n;
static boolean ans;
public static void dfs(int u, int path){
if(u == 10){
if(path == n){
ans = true;
}
return;
}
dfs(u + 1, path);
dfs(u + 1, path + p[u]);
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
p[0] = 1;
for(int i = 1; i <= 9; i ++){
p[i] = p[i - 1] * i;
}
while(true){
n = sc.nextInt();
ans = false;
if(n < 0){
break;
}
dfs(0, 0);
if(n == 0){
ans = false;
}
if(ans){
System.out.println("YES");
}
else{
System.out.println("NO");
}
}
}
}
思路二: 打表
时间复杂度
参考文献
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_set>
using namespace std;
const int N = 1e5+10;
int n;
int a[N];
unordered_set<int>s;
int main()
{
a[0]=a[1]=1;
for (int i = 1; i <= 9; i ++ )a[i]=a[i-1]*i;
for (int i = 0; i < 1<<10; i ++ )
{
int t=0;
for (int j = 0; j < 10; j ++ )
{
if(i>>j&1)t+=a[j];
s.insert(t);
}
}
while(cin>>n,n>=0)
{
if(n==0)puts("NO");
else if(s.count(n))puts("YES");
else puts("NO");
}
return 0;
}
Java代码
import java.util.*;
public class Main{
public static void main(String[] args){
// 预处理阶乘
int[] f = new int[10];
f[0] = f[1] = 1;
for(int i = 2; i <= 9; i++) f[i] = f[i-1] * i;
Set<Integer> set = new HashSet<>();
for(int i = 0; i < 1 << 10; i++){
int sum = 0;
for(int j = 0; j < 10; j++){
if(((i >> j) & 1) == 1){
sum += f[j];
}
}
set.add(sum);
}
Scanner sc = new Scanner(System.in);
while(true){
int n = sc.nextInt();
if(n < 0) break;
if(n == 0) System.out.println("NO");
else System.out.println(set.contains(n) ? "YES" : "NO");
}
}
}
GO代码
package main
import (
"fmt"
)
var x int
var nums [12]int
func main() {
label : fmt.Scanf("%d", &x)
m := make(map[int]bool)
nums[0] = 1
for i:= 1;i < 12;i ++ {
nums[i] = nums[i - 1] * i
}
for i:= 1 ; i< 1 << 10 ; i ++ {
s:= 0
for j := 0 ; j < 10 ; j ++ {
if i >> j & 1 == 1 {
s += nums[j]
}
}
if _, ok := m[s]; !ok {
m[s] = true
}
}
if x >= 0 {
if _, ok := m[x]; ok {
fmt.Println("YES")
}else {
fmt.Println("NO")
}
goto label
}
}
欢迎留言点赞
嗷嗷嗷~
最后
以上就是朴实汉堡为你收集整理的若干数阶乘的和的全部内容,希望文章能够帮你解决若干数阶乘的和所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复