7.20试机测 T3 阶乘之和 暴力AC题解
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题解的更多相关文章
- HPU 第三次积分赛:阶乘之和(水题)
阶乘之和 描述 对于整数pp,给出以下定义 p=x_{1}!+x_{2}!+x_{3}!+...+x_{q}!(x_{i}<x_{j}for\ all\ i<j )p=x1!+x2!+ ...
- nyoj阶乘之和
/*阶乘之和 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描写叙述 给你一个非负数整数n,推断n是不是一些数(这些数不同意反复使用,且为正数)的阶乘之和, 如9=1! ...
- PTA 阶乘之和取模
阶乘之和取模 (25 分) 输入正整数n, 计算S = 1!+2!+...+n!的末6位(不含前导0). 这里1<=n<=109. 输入样例: 例如输入: 20 输出样例: 输出: ...
- 7-49 求前n项的阶乘之和 (15 分)
从键盘输入一个整数n,求前n项的阶乘之和,1+2!+3!+...+n!的和 输入格式: 输入一个大于1的整数.例如:输入20. 输出格式: 输出一个整数.例如:2561327494111820313. ...
- Java实现 洛谷 P1009 阶乘之和
import java.util.Scanner; public class 阶乘之和 { public static void main(String[] args) { Scanner sc = ...
- nyoj 91 阶乘之和(贪心)
阶乘之和 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3! ...
- ACM 阶乘之和
阶乘之和 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3! ...
- 阶乘之和--nyoj91
描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3!,如果是,则输出Yes,否则输出No: 输入 第一行有一个整数0<m<10 ...
- nyoj 91 阶乘之和
点击打开链接 阶乘之和 时间限制:3000 ms | 内存限制:65535 KB 难度: 描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2 ...
随机推荐
- ElasticSearch中的sort排序和filedData作用
默认情况下,ElasticSearch 会根据算分进行排序: 可以使用 sort API 指定排序的规则: POST /kibana_sample_data_ecommerce/_search { & ...
- JavaWeb网上图书商城完整项目--day02-15.登录功能流程分析
当用户点击登录界面的登录按钮的时候,将登录的用户名.密码和验证码上传到后台,后台的业务流程如下面所示:
- Socket连接和Http连接
Socket连接与HTTP连接我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有 ...
- Quartz.Net系列(九):Trigger之DailyTimeIntervalScheduleBuilder详解
1.介绍 中文意义就是每日时间间隔计划生成 2.API讲解 (1)WithInterval.WithIntervalInHours.WithIntervalInMinutes.WithInterval ...
- 个人项目-Wc-Java
一.Github项目地址: https://github.com/Heiofungfming/xiaoming01 二.PSP表格 PSP2.1 任务内容 计划完成需要的时间(min) 实际完成需要的 ...
- Django实现图片上传并前端页面显示
Django实现图片上传和图片显示 开始之前我们先确认环境中已经安装了Pillow,如果没有安装,可以通过pip install Pillow来安装,这个是python的图像处理库 数据库设置 我们创 ...
- JavaScript基础函数的声明(014)
1.函数的重要地位 函数(functions)在JavaScript里有着重要的地位,其原因有二: 它们是一种特殊的对象 它们提供作用域 说函数在JavaScript里是特殊的对象,因为: 程序的执行 ...
- 第一步:安装centos_8
关于centos的安装其实大部分时候都是在虚拟机环境下安装. 好处无疑有这几个:方便,快速,主要就是整出事情了我可以直接删了重装 我这边是在vmware下进行一个安装 vmware我这边给出下载链接: ...
- Spring Security(三) —— 核心配置解读
摘要: 原创出处 https://www.cnkirito.moe/spring-security-3/ 「老徐」欢迎转载,保留摘要,谢谢! 3 核心配置解读 上一篇文章<Spring Secu ...
- (二)LVS介绍
LVS分3种模式 (a)NAT(网络地址映射):通过网络地址转换的方法来实现调度 优点:支持所有操作系统及私有网络,且只需一个公网 IP 地址 缺点:用户请求和响应报文都必须 ...