7.20试机测  T3 阶乘之和 暴力AC题解

题外话:此乃本蒟蒻发表的第一篇题解,大家多多关照,支持一下,谢谢


题面

3、阶乘之和(sum.pas/in/out)

问题描述: 给定一个非负整数 n,请你判断 n 是否可以由一些非负整数的阶乘相加得到。

问题输入: 有若干组数据。每行一个整数 n,保证 n<1000000。 以负数结束输入。

问题输出: 对于每组数据输出一行,若可以则输出‘YES’,否则输出‘NO’。

输入样例: 9 -1

样例输出: YES


分析

这个题嘛

大概了解了一下题意,就是给出n,判断n能不能被几个数的阶乘加起来。(虽然题目没有说清楚数字能不能重复,但是我们知道1的阶乘是1,如果数字可以重复的话,那么任何n都是YES了,所以我推测所选数字不能重复)


题目让输入多组数据,我们先针对一个数据进行操作,在结尾再弄关于输入多组数据的问题…………

下面算出一些较小数的阶乘(千万不要忘记0)(这一步可以在Excel完成,用FACT函数)

看到数据范围, n<1000000,可以了解到所选的数字应该在0~9里。

那么,n的最大值就确定了,即0~9的阶乘之和(1+1+2+6+24+...+40320+362880=409114)

也就是说,只要n的值超过了409114,那么这个n就不符合条件,可以提前判断一部分n是不是NO。

还有,0的阶乘是1,那么如果n的值为0,就没有非负整数满足n,也是直接NO。

if(n> || n==)
cout<<"NO"<<endl;

下面怎么办呢,暴力?!

在这里,我还没有学一些什么神奇01背包,二进制什么玩意……

我就简简单单地用几个for循环来搜出所有情况吧。

先开一个数组(第一个开0是防止有??的情况   其实第一个完全可以不开0,不开0还节省了时间)

long long x[]= {,,,,,,,,,,};

我们知道,题目给定一个n,这个n可能由上面数组中的1个数相加得到,也可能是2个,也可能是多个……

(比如n=4时,n是1+1+2,由数组中的3个数相加得到;n=25时,则为1+24,由数组中的2个数相加得到)

那么,我们先假设n由上面选1个数得到,则可以

for(int a=; a<; ++a)
if(x[a]==n)
{
cout<<"YES"<<endl;
}

如果一个数不行,那就看看2个数加起来能不能得到n

这里防止有判重的情况,就让b=a+1,还节省了时间。

for(int a=; a<; ++a)
for(int b=a+; b<; ++b)
if(x[a]+x[b]==n)
{
cout<<"YES"<<endl;
}

下面以此类推……直到10个数的时候

for(int a=; a<; ++a)
for(int b=a+; b<; ++b)
for(int c=b+; c<; ++c)
for(int d=c+; d<; ++d)
for(int e=d+; e<; ++e)
for(int f=e+; f<; ++f)
for(int g=f+; g<; ++g)
for(int h=g+; h<; ++h)
for(int i=h+; i<; ++i)
for(int j=i+; j<; ++j)
if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]+x[h]+x[i]+x[j]==n)
{
cout<<"YES"<<endl;
}

这样就行了?此处忽略了一个地方,假设n由5个数相加就能得到,那么下面的6次,7次循环再执行岂不是浪费掉了时间嘛。

所以,我们开一个布尔变量,用来判断n是不是已经被配对了

bool yes=false;

好了,现在我们可以研究输入多组数据的问题了,因为不研究这个,布尔变量就没法展现它的作用。

题意说输入负数的时候结束程序(千万不要被样例迷惑了,不一定是-1结束程序)

那么,可以用while循环输入数据。

每输入一个n,就对n执行一次下面的操作。 直到n<0时,return 0 结束程序。

<0

int main()
{
while(scanf("%d",n) && n>=)
{
yes=false;
//此处往下写程序,每次当n配对时,把布尔变量变成true。
}
  return 0;
}

当n被配对时,变量yes的值为true。我们可以在程序中疯狂检测 yes的值,只要是true就立即让它输出“YES”,然后扔掉此时的n,再对下一个数字n进行操作。

具体操作如下(拿n由4个数相加得到 举例):

        for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c)
{
for(int d=c+; d<; ++d)
if(x[a]+x[b]+x[c]+x[d]==n)
{
cout<<"YES"<<endl;
yes=true; //只要n被配对成功,就把布尔设为true
break;
}
if(yes==true) break; //让被配对成功的n 一路顺风,跳出循环
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue; //此时的 continue 与 while 读入操作在同一层。这样就可以读入下一个n了

这样看起来好像有点麻烦,但是我觉得理解起来不难吧qwq.

最后当10次循环都走一遍,结果n没有找到合适的数字,就在末尾输出“NO”.


AC代码:

 /*---------------------------------
*Title number: 7.20 试机测 T3 阶乘之和
*Creation date: 2020-07-20 afternoon
*By: EdisonBa
*-------------------------------*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; long long x[]= {,,,,,,,,,,};
long long n;
bool yes=false; int main()
{
while(cin>>n && n>=)
{
yes=false; //每一次对n操作都要重置一下布尔变量 yes

//下面判一下最大值和0

if(n> || n==)
{
cout<<"NO"<<endl;
continue;
}

//下面进行第 1 次循环

for(int a=; a<; ++a)
if(x[a]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
} if(yes==true) continue;

//下面进行第 2 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b) if(x[a]+x[b]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
} if(yes==true) continue;

//下面进行第 3 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c) if(x[a]+x[b]+x[c]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue;

//下面进行第 4 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c)
{
for(int d=c+; d<; ++d)
if(x[a]+x[b]+x[c]+x[d]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue;

//下面进行第 5 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c)
{
for(int d=c+; d<; ++d)
{
for(int e=d+; e<; ++e)
if(x[a]+x[b]+x[c]+x[d]+x[e]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue;

//下面进行第 6 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c)
{
for(int d=c+; d<; ++d)
{
for(int e=d+; e<; ++e)
{
for(int f=e+; f<; ++f)
if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue;

//下面进行第 7 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c)
{
for(int d=c+; d<; ++d)
{
for(int e=d+; e<; ++e)
{
for(int f=e+; f<; ++f)
{
for(int g=f+; g<; ++g)
if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue;

//下面进行第 8 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c)
{
for(int d=c+; d<; ++d)
{
for(int e=d+; e<; ++e)
{
for(int f=e+; f<; ++f)
{
for(int g=f+; g<; ++g)
{
for(int h=g+; h<; ++h)
if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]+x[h]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue;

//下面进行第 9 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c)
{
for(int d=c+; d<; ++d)
{
for(int e=d+; e<; ++e)
{
for(int f=e+; f<; ++f)
{
for(int g=f+; g<; ++g)
{
for(int h=g+; h<; ++h)
{
for(int i=h+; i<; ++i) if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]+x[h]+x[i]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue;

//下面进行第 10 次循环

for(int a=; a<; ++a)
{
for(int b=a+; b<; ++b)
{
for(int c=b+; c<; ++c)
{
for(int d=c+; d<; ++d)
{
for(int e=d+; e<; ++e)
{
for(int f=e+; f<; ++f)
{
for(int g=f+; g<; ++g)
{
for(int h=g+; h<; ++h)
{
for(int i=h+; i<; ++i)
{
for(int j=i+; j<; ++j)
if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]+x[h]+x[i]+x[j]==n)
{
cout<<"YES"<<endl;
yes=true;
break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
}
if(yes==true) break;
} if(yes==true) continue;

// 10次循环完毕,若n没有合适的数字,输出"NO" cout<<"NO"<<endl; } return ;
}

https://www.luogu.com.cn/record/35414283

(此代码对于 第10个毒瘤点来说 能过就是奇迹)


这份代码,显然不是最优解(第10个测试点的时间快要爆了),如果把x数组里的0删去,可能时间会稍微短那么几毫秒。

但是这个理解起来很容易,只要有充足的时间就能写出来(大概半个多小时)。

我觉得这个代码的关键就是在每次大循环中,下层的for的变量值是上层的变量值+1(无法表述啊这)

-----------------------------------------------------------------------------------------------------------------------------------------------

看图:

-----------------------------------------------------------------------------------------------------------------------------------------------

这样节省了大部分时间,也防止出现了判重的情况,使得多次大循环顺利过测试点。


感谢您观看此题解。

这是本蒟蒻发表的第一篇题解,岂不妙哉?!

希望在接下来的时间里,大家共同成长,共同进步,多多交流,共创辉煌!

EdisonBa

2020/7/20

7.20试机测 T3 阶乘之和 暴力AC题解的更多相关文章

  1. HPU 第三次积分赛:阶乘之和(水题)

    阶乘之和 描述 对于整数pp,给出以下定义 p=x_{1}!+x_{2}!+x_{3}!+...+x_{q}!(x_{i}<x_{j}for\ all\ i<j )p=x1​!+x2​!+ ...

  2. nyoj阶乘之和

     /*阶乘之和 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 给你一个非负数整数n,推断n是不是一些数(这些数不同意反复使用,且为正数)的阶乘之和, 如9=1! ...

  3. PTA 阶乘之和取模

    阶乘之和取模 (25 分) 输入正整数n, 计算S = 1!+2!+...+n!的末6位(不含前导0). 这里1<=n<=10​9​​. 输入样例: 例如输入: 20 输出样例: 输出: ...

  4. 7-49 求前n项的阶乘之和 (15 分)

    从键盘输入一个整数n,求前n项的阶乘之和,1+2!+3!+...+n!的和 输入格式: 输入一个大于1的整数.例如:输入20. 输出格式: 输出一个整数.例如:2561327494111820313. ...

  5. Java实现 洛谷 P1009 阶乘之和

    import java.util.Scanner; public class 阶乘之和 { public static void main(String[] args) { Scanner sc = ...

  6. nyoj 91 阶乘之和(贪心)

    阶乘之和 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3! ...

  7. ACM 阶乘之和

    阶乘之和 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3! ...

  8. 阶乘之和--nyoj91

    描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3!,如果是,则输出Yes,否则输出No: 输入 第一行有一个整数0<m<10 ...

  9. nyoj 91 阶乘之和

    点击打开链接 阶乘之和 时间限制:3000 ms  |  内存限制:65535 KB 难度: 描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2 ...

随机推荐

  1. 入门大数据---SparkSQL常用聚合函数

    一.简单聚合 1.1 数据准备 // 需要导入 spark sql 内置的函数包 import org.apache.spark.sql.functions._ val spark = SparkSe ...

  2. Python实用笔记 (20)面向对象编程——继承和多态

    当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base class.Super class). ...

  3. 理解与使用Javascript中的回调函数 -2

    在javascript中回调函数非常重要,它们几乎无处不在.像其他更加传统的编程语言都有回调函数概念,但是非常奇怪的是,完完整整谈论回调函数的在线教程比较少,倒是有一堆关于call()和apply() ...

  4. 半导体质量管理(LineWorks)_SPACE(统计过程分析和控制环境)

    LineWorks作为SEMI的质量管理,可为半导体制造商提供对实施标准,产品质量,质量和指标验证的全面控制.有许多附加模块和SPACE-Chart插件,可根据个人需求进行灵活调整. 三个主要特征是: ...

  5. pycharm中连接MySql出现 Exception in thread "main" java.lang.ClassNotFoundException: com.mysql.jdbc.的错误解决

    具体异常如下: 这个异常特别烦人,是mysql连接驱动的问题,可以用二步解决: 第一步 从网上下载驱动,从mysql-connector-java_8.0.16-1ubuntu16.04_all.de ...

  6. Spring事务的传播级别

    一.简单说明 传播属性 描述 PROPAGATION_REQUIRED 如果当前没有事务,就创建一个事务,如果当前存在事务,就加入该事务. PROPAGATION_REQUIRED_NEW 当前的方法 ...

  7. C语言学习笔记第一章——开篇

    本文章B站有对应视频 (本文图片.部分文字引用c primer plus) 什么是C语言 顾名思义,c语言是一门语言,但是和我们所讲的话不同,它是一门编程语言,是为了让机器可以听懂人的意思所以编写的一 ...

  8. 聊聊Java

    聊聊Java 笔记源于 视频教程Bilibili:狂神说Java 关注公众号:狂神说 能干嘛? 热度 TIOBE 狂神计划 三高:高可用.高性能.高并发 全球几千万的程序员都会Java,真正精通的不到 ...

  9. 冷知识:达夫设备(Duff's Device)效率真的很高吗?

    ID:技术让梦想更伟大 作者:李肖遥 wechat链接:https://mp.weixin.qq.com/s/b1jQDH22hk9lhdC9nDqI6w 相信大家写业务逻辑的时候,都是面向if.el ...

  10. 转载--- 写给Node.js学徒的7个建议

    贴士 1: 在开发环境使用nodemon,在生产环境使用pm2 当你第一次开发Node.js应用的时候, 其中一件事情就是一次又一次的运行[file].js 就和揭伤疤一样. 当我第一次开发的node ...