You will get a non-negative integer n (n≤1,000,000) from input file.
For the n in the input file, you should print exactly one word ("YES" or "NO") in a single line. No extra spaces are allowed.
9 2
YES YES
#include<iostream>
using namespace std;
int main(){
int n;
int a[11];
for(int i=1;i<11;i++){
if(i==1) a[i]=1;
else a[i]=i*a[i-1];
}
while(cin>>n){
for(int i=10;i>0;i--){
if(n>=a[i])
n-=a[i];
}
if(n>1){
cout<<"NO"<<endl;
}
else cout<<"YES"<<endl;
}
}
while True:
try:
num = int(input())
factor = [1]*10
for i in range(2,10): #因为输入最大1000000,所以前十个阶乘就可以了
factor[i] = factor[i-1]*i
index = 9
while index >= 0: #一直减,能减就减,因为阶乘大于其前面所有阶乘的和
if num >= factor[index]:
num -= factor[index]
index -= 1
if num == 0: #如果减空了说明能分解为阶乘之和
print('YES')
else:
print('NO')
except Exception:
break
#include<stdio.h>//依题之意判断n是否等于连续的阶乘和
int main()//10的阶乘为3628800,n一定小于10的阶乘,所以算出10以前的阶乘即可
{
int n,i,a[10];//a[i]代表i的阶乘
a[0]=1;
for(i=1;i<10;i++)//求1-9的阶乘
a[i]=a[i-1]*i;
while(scanf("%d",&n)!=EOF)
{
for(i=9;i>=0;i--)//添加一个n==0时结束循环的语句也可以
if(n>=a[i])
n-=a[i];
if(n==0)
printf("YES\n");
else
printf("NO\n");
}
} #include<iostream>
using namespace std;
int main()
{
int n,a[10];
a[0] = 1;
for(int i=1;i<=10;i++)
a[i] = a[i-1]*i;
while(cin>>n)
{
if(n==0) cout<<"NO"<<endl;
for(int i=10;i>=0;i--)
{
if(n>=a[i]) n-=a[i];
}
if(n==0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
} 能减就减,因为n!一定大于前n - 1个数的阶乘的和
#include<iostream>
using namespace std;
int f[10];
int main(){
f[0] = 1;
for(int i = 1; i < 10; i++)
f[i] = f[i - 1] * i;
int n;
while(cin >> n){
for(int i = 9; i >= 0; i--){
if(n >= f[i]){
n -= f[i];
}
}
if(n == 0){
cout << "YES" << endl;
}
else{
cout << "NO" << endl;
}
}
return 0;
}
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int fact[10];
fact[0] = fact[1] = 1;
for(int i=2;i<10;i++)
{
fact[i] = fact[i-1]*i;
}
bool seq[1000001];
for(int i=0;i<=1000000;i++)
{
seq[i] = false;
}
for(int i=0;i<1024;i++)
{
int t = i;
int sum = 0;
for(int i=0;i<10;i++)
{
if(t%2==1)
sum += fact[i];
t /= 2;
}
seq[sum]=true;
}
int n;
cin >> n;
if(seq[n]==true)
cout << "YES";
else
cout << "NO";
return 0;
}
其实就是先把所有可以表示的数算出来。一共就10个元素,所有的组合算出来也就2^10个数需要算,每一种组合都可以用0(或1)——1023中的一个数表示。
//用递归写的
#include<iostream>
using namespace std;
#include<vector>
vector<int> fac;
void init(){
int t=1;
fac.push_back(t);
for(int i=1;t<=1000000;i++){
t *= i;
fac.push_back(t);
}
}
bool solve(int m, int maxf){
if(m==0)return true;
else if(m<0)return false;
if(maxf<0)return false;
return solve(m-fac[maxf],maxf-1) || solve(m,maxf-1);
}
int main(){
int num;
init();
while(cin>>num){
int maxf=fac.size();
while(fac[maxf]>num)
maxf--;
cout<<(solve(num,maxf)?"YES":"NO")<<endl;
}
}
#include <iostream>
using namespace std;
int main() {
int n, i;
int a[11];
a[0] = 1;
for (int i = 1; i <= 10; i++) {
a[i] = a[i - 1] * i;
}
while (cin >> n) {
for (int i = 10; i >= 0; i--) {
if (n >= a[i]) {
n -= a[i];
}
}
if (n > 0) {
cout << "NO" << endl;
}
else {
cout << "YES" << endl;
}
}
return 0;
}
#include <stdio.h>
(737)#include <string.h>
const int N = 1000000;
const int M = 11;
int n;
int fact[M];
int maxIndex = 0;
bool ans = false;
void DFS(int curIndex,int sum) {
if(curIndex > maxIndex || sum + fact[curIndex] > n) return;
if(sum + fact[curIndex] == n){
ans = true;
return;
}
DFS(curIndex+1,sum + fact[curIndex]);
DFS(curIndex+1,sum);
}
int main() {
scanf("%d",&n);
fact[0] = 1;
while(maxIndex < M && fact[maxIndex] <= n) {
maxIndex++;
fact[maxIndex] = fact[maxIndex-1] * maxIndex;
}
DFS(0,0);
char str[5];
if(ans)
strcpy(str,"YES");
else
strcpy(str,"NO");
printf("%s",str);
return 0;
} #include <stdio.h>
(737)#include <string.h>
const int N = 1000000;
const int M = 11;
int n;
int fact[M];
int maxIndex = 0;
bool dp[N];
bool ans = false;
void bag() {
dp[0] = true;
for(int i = 0; i <= maxIndex; i++)
for(int j = n; j >= fact[i]; j--)
if(dp[j] == true || dp[j - fact[i]] == true)
dp[j] =true;
}
int main() {
scanf("%d",&n);
fact[0] = 1;
while(maxIndex < M && fact[maxIndex] <= n) {
maxIndex++;
fact[maxIndex] = fact[maxIndex-1] * maxIndex;
}
bag();
ans = dp[n];
char str[5];
if(ans)
strcpy(str,"YES");
else
strcpy(str,"NO");
printf("%s",str);
return 0;
} #include <iostream>
#include<vector>
using namespace std;
int main() {
//这里其实是使用的是暴力搜索,先创建一个数组用来存储1-10的阶乘的结果,
//由于10!已经是大于1000000了,因此其已经够对于n的值的搜索
//这里注意0!=1,这里是可以使用的如:4=0!+1!+2!,因此输出为YES
vector<int>dp(11);
dp[0] = 1;
for (int i = 1; i <= 10; i++) {
dp[i] = dp[i - 1] * i;
}
int n;
while (cin >> n) {
for (int i = 10; i >= 0; i--) {
if (n >= dp[i])
n = n - dp[i];
if (n == 0) {
cout << "YES" << endl;
break;
}
}
if (n != 0)cout << "NO" << endl;
}
} def mul(a):
s = 1
if a == 0&nbs***bsp;a == 1:
return 1
for i in range(1,a+1):
s *= i
return s
def fac_s(sum, target, i):
if sum == target:
#print('YES')
return True
if sum > target:
return False
for j in range(i, 11):
sum+=mul(j)
if fac_s(sum, target, j+1):
return True
sum -= mul(j)
return False
def p(a):
return fac_s(0, a, 0)
while True:
try:
a = int(input())
if p(a):
print('YES')
else:
print('NO')
except:
break
#include <bits/stdc++.h>
using namespace std;
// 转换成01背包问题
// 求xi的阶乘
int xi(int n) {
int sum = 1;
for(int i=1;i<=n;++i) {
sum *= i;
}
return sum;
}
int main() {
int n;
while(cin >> n && n != 0) {
vector<int> dp(n+1, 0);
for(int i=0;xi(i)<=n;++i) {
for(int j=n;j>=xi(i);--j) {
dp[j] = max(dp[j], dp[j-xi(i)]+xi(i));
}
}
if(dp[n] == n)
cout << "YES\r\n";
else
cout << "NO\r\n";
}
return 0;
} 将每个数 xi 看成是体积为 xi! 的物品,而 dp[j] 数组的含义是容量为 j 大小的背包最多可以放入多大容积的物品。所以只要确认最后 dp[n] == n 即可判断n大小的背包是否可以刚刚好被装满,从而输出YES or NO #include <iostream>
using namespace std;
int factorial(int n) { //求阶乘
return n <= 1 ? 1 : n * factorial(n - 1);
}
int main() {
int n;
while (cin >> n) {
for (int i = 9; i >= 0; i--) {
int factorial_i = factorial(i);
if (n >= factorial_i) {
n -= factorial_i;
}
}
cout << (n == 0 ? "YES" : "NO") << endl;
}
return 0;
} // https://www.nowcoder.com/practice/42cb1c7f7344466b8cb1710cb12d06b1?tpId=62&tqId=29456&tPage=1&rp=1&ru=/ta/sju-kaoyan
// 疏忽的点,0 的阶乘是 1 !!!
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
bool can_be_sum=false;
int n;
vector<int> factorials;
// vector<int> visited; 一维单向,可以不需要这个数组标记
void dfs(int cur_sum, int idx){
if(cur_sum == n){
can_be_sum = true;
return ;
}
else if(cur_sum > n) return ;
if(idx==factorials.size()) return ;
dfs(cur_sum+factorials[idx], idx+1);
dfs(cur_sum, idx+1);
return ;
}
int main(){
factorials.push_back(1);
int fact=1;
for(int i=1; fact<=1000001; ++i){
fact *= i;
factorials.push_back(fact);
}
string ret;
while(cin >> n){
can_be_sum = false;
dfs(0, 0);
ret = can_be_sum ? "YES" : "NO";
cout << ret << endl;
}
return 0;
} #include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 15;
//判断输入的数是不是连续的阶乘之和和,(n≤1,000,000)
int dp[maxn] = {0};//阶乘表
int f(int n) {
if(n == 0 || n == 1) return 1;
if(dp[n] != 0) return dp[n];
else return dp[n] = n * f(n - 1);
}
bool flag = false;
//判断从i到j的阶乘和是否为n
void DFS(int i, int j, int n) {
//边界
while(dp[j]> n) --j;
if(i > j || n < 0) return;
if(n - dp[j] == 0) {
flag = true;
return;
}
DFS(i, j - 1, n - dp[j]);
}
int main () {
f(10); //打印阶乘表
dp[0] = dp[1] = 1;
int n;
while(scanf("%d", &n) != EOF) {
DFS(0, 10, n);
if(flag) printf("YES");
else printf("NO");
}
return 0;
}
两个DP思路:
1、n是否可以表示。拆解为n-x是否可以表示,但会出现阶乘重复使用的问题。
2、每个数选或不选,即0-1背包问题。
提前计算出所有<=n的阶乘。问题转化为从一个有序数组中找出若干个,每个只能用一次,使其和等于一个特定数。每个数有选和不选两种状态,这就是经典的0-1背包问题。本题还可以做空间优化。
#include <cstdio>
(802)#include <vector>
using namespace std;
int main(){
int n, temp=1, x=1;
scanf("%d", &n);
vector<int> fac;
while(temp<=n){
fac.emplace_back(temp);
temp *= x;
x++;
}
int m = x-1;
bool dp[n+1]={};
dp[0] = true;
for(int k=1; k<=m; k++){
for(int t=n; t>=0; t--){
dp[t] = t>=fac[k-1] ? (dp[t] || dp[t-fac[k-1]]) : dp[t];
}
}
if(dp[n]) printf("YES");
else printf("NO");
return 0;
}
//注意4也是可以的,因为0!+1!+2!=4,即不要忘了0的阶乘
#include<iostream>
using namespace std;
int result(int x){
if(x==0)
return 1;
else
return x*result(x-1);
}
int main(){
int n,i,a[10],temp;
for(i=0;i<=9;i++)
a[i]=result(i);
while(cin>>n){
int sum=n;
int flag=1;
for(i=0;i<=9;i++)
if(a[i]>n){
temp=i;
break;
}
for(i=temp-1;i>=0;i--){
if(sum-a[i]<0)
continue;
sum=sum-a[i];
if(sum==0){
cout<<"YES"<<endl;
flag=0;
break;
}
}
if(flag==1)
cout<<"NO"<<endl;
}
return 0;
}