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. ElasticSearch中的sort排序和filedData作用

    默认情况下,ElasticSearch 会根据算分进行排序: 可以使用 sort API 指定排序的规则: POST /kibana_sample_data_ecommerce/_search { & ...

  2. JavaWeb网上图书商城完整项目--day02-15.登录功能流程分析

    当用户点击登录界面的登录按钮的时候,将登录的用户名.密码和验证码上传到后台,后台的业务流程如下面所示:

  3. Socket连接和Http连接

    Socket连接与HTTP连接我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有 ...

  4. Quartz.Net系列(九):Trigger之DailyTimeIntervalScheduleBuilder详解

    1.介绍 中文意义就是每日时间间隔计划生成 2.API讲解 (1)WithInterval.WithIntervalInHours.WithIntervalInMinutes.WithInterval ...

  5. 个人项目-Wc-Java

    一.Github项目地址: https://github.com/Heiofungfming/xiaoming01 二.PSP表格 PSP2.1 任务内容 计划完成需要的时间(min) 实际完成需要的 ...

  6. Django实现图片上传并前端页面显示

    Django实现图片上传和图片显示 开始之前我们先确认环境中已经安装了Pillow,如果没有安装,可以通过pip install Pillow来安装,这个是python的图像处理库 数据库设置 我们创 ...

  7. JavaScript基础函数的声明(014)

    1.函数的重要地位 函数(functions)在JavaScript里有着重要的地位,其原因有二: 它们是一种特殊的对象 它们提供作用域 说函数在JavaScript里是特殊的对象,因为: 程序的执行 ...

  8. 第一步:安装centos_8

    关于centos的安装其实大部分时候都是在虚拟机环境下安装. 好处无疑有这几个:方便,快速,主要就是整出事情了我可以直接删了重装 我这边是在vmware下进行一个安装 vmware我这边给出下载链接: ...

  9. Spring Security(三) —— 核心配置解读

    摘要: 原创出处 https://www.cnkirito.moe/spring-security-3/ 「老徐」欢迎转载,保留摘要,谢谢! 3 核心配置解读 上一篇文章<Spring Secu ...

  10. (二)LVS介绍

    LVS分3种模式  (a)NAT(网络地址映射):通过网络地址转换的方法来实现调度       优点:支持所有操作系统及私有网络,且只需一个公网 IP 地址       缺点:用户请求和响应报文都必须 ...