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. django python mange.py runserver 源码

    django python mange.py runserver 源码 入 口 mange.py文件 execute_from_command_line函数 输入参数为['manage.py', 'r ...

  2. django drf插件(一)

    复习 """ 1.vue如果控制html 在html中设置挂载点.导入vue.js环境.创建Vue对象与挂载点绑定 2.vue是渐进式js框架 3.vue指令 {{ }} ...

  3. 程序员必备基础:Git 命令全方位学习

    前言 掌握Git命令是每位程序员必备的基础,之前一直是用smartGit工具,直到看到大佬们都是在用Git命令操作的,回想一下,发现有些Git命令我都忘记了,于是写了这篇博文,复习一下~ https: ...

  4. Java 从入门到进阶之路(二十五)

    在之前的文章我们介绍了一下 Java 中的  集合框架中的Collection 的子接口 List的 增删改查和与数组间相互转换的方法,本章我们来看一下 Java 集合框架中的Collection 的 ...

  5. excel把按行合并的单元格重新拆分

    前言 今天帮朋友弄她excel表格的数据,发现excel表格合并之后,再拆分就不再同一行里面了,导致后面想要拆分回来非常头痛,如下图(下面的数据是模拟的): 可以看到第一例和其他例中间部分为合并的,此 ...

  6. (私人收藏)精美PPT模板

    精美PPT模板 https://pan.baidu.com/s/1vsRnX5h7t3MZ7qdrFvuI1wsucr

  7. 听说你还没学Spring就被源码编译劝退了?30+张图带你玩转Spring编译

    源码学习第一步,Spring源码编译 之所以写这么一篇文章是因为群里的小伙伴在编译源码时碰到了问题,再加上笔者自身正准备做一个源码的注释版本,恰好也需要重新编译一份代码,至于为什么要将源码编译到本地就 ...

  8. SpringMVC+Spring+Hibernate个人家庭财务管理系统

    项目描述 Hi,大家好,今天分享的项目是<个人家庭财务管理系统>,本系统是针对个人家庭内部的财务管理而开发的,大体功能模块如下: 系统管理模块 验证用户登录功能:该功能主要是验证用户登录时 ...

  9. 「HAOI2015树上染色」「树形DP」

    其实我还不大会树形DP 此题就当练手叭,缕一下思路就好 题目链接 BZOJ4033 题目大意就是给一棵树,对一部分点染成黑色,剩下的为白色,问所有同色点距离之和....... 简明扼要的题意,然额我不 ...

  10. Codeforces 1215D Ticket Game 题解

    Codeforces 1215D Ticket Game 原题 题目 Monocarp and Bicarp live in Berland, where every bus ticket consi ...