poj 1775 Sum of Factorials

题目大概意思是:让判断一个数n是否能够用若干个数的阶乘之和表示

例如9=1+2+3

其中有一句我觉得有问题,导致我多提交一次 就是Σ1<=i<=txi!. (t >=1 1, xi >= 0, xi = xj if( i = j).就是说xi==xj的时候i==j 但是 0==1!但是i=j这可怎么办啊于是我就把0!擅自改成了结果错了,后来又改成结果就对了,哎!深深体会到语言表达的重要性啊

一开始我是怎么想的呢,n不超过1000000 最大也就10! 开一个长度为10 的数组然后搜索,可惜超时,后来看别人的,我才忽然想到阶乘是由它自己的性质的

一个数 a>b 

for(i=0;i<=b;i++)

sum+=i!;

那么重点来了哦, a>=sum; 当 a=2; b=1;时等号成立

所以本题直接利用这个性质,将用n减去小于的书的阶乘,一直往下减,看是否能够减到如果可以答案就是yes否则嘿嘿……

代码:

#include <iostream>
#include <cstring>
using namespace std;
int map[11];
int n;
void init()
{
 int s=1;
 int i;
 map[0]=1;
 map[1]=1;
 for(i=2;i<=10;i++)
 {
 s*=i;
 map[i]=s;
 }
}
int solve()
{
 int i;
 for(i=10;i>=0;i--)
 if(n-map[i]==0)
 return 1;
 else if(n-map[i]>0)
 n-=map[i];
 return 0;
}
int main()
{
 init();
 while(scanf("%d",&n)!=EOF)
 {
 if(n<0)//此处注意切不可写 if(n==-1) break; 否则会出错的,测试数据中可能会包含非-1 其他的负数
 break;
 if(solve()==0)
 printf("NO\n");
 else 
 printf("YES\n");
 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值