哈喽,我是飞鸟,欢迎阅读,有问题可以一起交流,点赞,关注我
在进行归纳推理时,如果逐个考察了某类事件的所有可能情况,因而得出一般结论,那么这结论是可靠的,这种归纳方法叫做枚举法.
枚举法,也叫暴力破解法,是一种基于逐个尝试答案的一种问题求解策略。
最开始接触算法的时候,大家练习的基础算法都是有关于枚举算法的,比如打印出9 * 9的乘法表,求水仙花数,求素数等等,像这一类的题目就是在一定的范围内寻找满足条件的答案。
枚举算法的核心思想就是:枚举所有的可能
美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。 一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,他回答说:“我年龄的立方 是个4位数。我年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”请你推算一下,他当时到底有多年轻。直接提交他那时的年龄数字。
通过暴力破解的方法,找到年龄的大概范围,假设他的年龄为x,10^3=1000, 30^4=8100,说明x的范围在[10,30]之间。
int main(){
for(int i = 10;i <= 30;i++)
{
printf("%d= %.0f %.0f\n",i,pow(i,3),pow(i,4));//pow指i的立方,i的四次方
}
return 0;
}
结果:
某君新认识一网友。当问及年龄时,他的网友说:“我的年龄是个2位数,我比儿子大27岁,
如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄”
请你计算:网友的年龄一共有多少种可能情况?
提示:30岁就是其中一种可能哦.
请填写表示可能情况的种数。
网友的年龄比他儿子大27,就说明网友至少27岁,即为初始值为27,两位数最大也就是99,范围【27,99】,假设网友年龄为i,设个位为b,十位数为10a,把他的年龄数字交换位置正好是他的儿子的年龄,那么他儿子的年龄为10b+a,判断条件是网友的年龄减去27等于他儿子的年龄,sum累加几种可能性。
#include
#include
int main()
{
int i,a,b,son,sum=0;
for(i=27;i<100;i++){
a=i/10;
b=i%10; //例如41对10整除取4,对10取余得1,即他儿子14岁
son=(b*10)+a;
if(27==i-son){
printf("%d\n",i);
sum++;
}
}
printf("共有%d种可能性\n",sum);
return 0;
}
结果:
30
41
52
63
74
85
96
共有7种可能性
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。现在算起来,他一共吹熄了236根蜡烛。
请问,他从多少岁开始过生日party的?
请输出他开始过生日party的年龄数。
注意:你输出的应该是一个整数,不要输出任何多余的内容或说明性文字。
输入
没有输入。
输出
输出一个整数,即某君开始过生日party的年龄数
提示
用printf或cout输出答案。
假设i为初始年龄,j为终止年龄,j肯定要大于i,那么j=i+1,k为多少根蜡烛!暴力累加。
int main()
{
for(int i=1;i<=100;i++)
{
for(int j=i+1;j<=100;j++)
{
int sum=0;
for(int k=i;k<=j;k++){
sum += k;
}
if(sum==236)
printf("%d",i);
}
}
return 0;
}
结果:26
有限五位数
个位数为6且能被3整除的五位数有多少个?
首先分析5位数的范围【10000,99999】,个位数为6说明至少两位数,并对3取余,ans累加。
#include
#include
int main() {
int ans=0;
for(int i=10000;i<=99999;i++){
if((i*10+6)%3==0){
ans++;
}
}
printf("能被3整除的有%d个",ans);
return 0;
}
结果:能被3整除的有3000
个
小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。有一次,老师出的题目是:36 x 495 =? 他却给抄成了:396 x 45 = ? 但结果却很戏剧性,他的答案竟然是对的!! 因为 36 * 495 = 396 * 45= 1782 类似这样的巧合情况可能还有很多,比如:27* 594 = 297 * 54
假设 a b c d e 代表1~9不同的5个数字(注意是各不相同的数字,且不含0)
能满足形如: ab * cde = adb* ce 这样的算式一共有多少种呢?请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
答案直接通过浏览器提交。注意:只提交一个表示最终统计种类数的数字,不要提交解答过程或其它多余的内容。
假设a b c d e 代表1~9不同的5个数字,a b c d e的范围在【1,9】,有多少种结果用ans累加法,通过判断条件abcde=adbce满足条件累加1,然后有一种可能就是a与b相等,所以判断否定a不等于b,其他字母也一样。
#include
int main(){
int ans=0,m,n;
for(int a = 1;a<=9;a++){
for(int b = 1;b<=9;b++){
for(int c = 1;c<=9;c++){
for(int d =1;d<=9;d++){
for(int e =1;e<=9;e++){
m = (a*10+b)*(c*100+d*10+e);
n = (a*100+d*10+b)*(c*10+e);
if(m==n&&a!=b&&a!=c&&a!=d&&a!=e&&b!=c&&b!=d&&b!=e&&c!=d&&c!=e&&d!=e){
ans++;
}
}
}
}
}
}
printf("一共%d种",ans);
return 0;
}
结果:142
上小学的时候,小明经常自己发明新算法。一次,老师出的题目是: 1/4 乘以 8/5 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45。老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!
对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢? 请写出所有不同算式的个数(包括题中举例的)。
显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。
但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!
注意:答案是个整数(考虑对称性,肯定是偶数)。
请通过浏览器提交。不要书写多余的内容。
其实跟上一道差不多,找出范围,找出判断条件,找出不符合条件,利用累加ans
注意不可以用(a/b)*(c/d)==((a*10+c)/b*10+d)),而是利用数学里面的十字相乘法
#include
int main(){
int ans=0;
for(int a=1;a<=9;a++){
for(int b =1;b<=9;b++){
for(int c =1;c<=9;c++){
for(int d=1;d<=9;d++){
if(a==b&&c==d)
continue;
int e = a*10+c,f = b*10+d;
if(a*c*f==b*d*e){
ans++;
}
}
}
}
}
printf("%d",ans);
return 0;
}
结果:14
小蓝有一个超大的仓库,可以摆放很多货物。现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。小蓝希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上分别堆 L 、 W 、 H 的货物,满足 n = L × W × H。给定 n ,请问有多少种堆放货物的方案满足要求。
例如,当 n = 4 时,有以下 6 种方案: 1 × 1 × 4 、 1 × 2 × 2 、 1 × 4 × 1 、 2 × 1 × 2 、 2 × 2 × 1 、 4 × 1 × 1
请问,当 n = 2021041820210418 (注意有 16位数字)时,总共有多少种方案?
提示:建议使用计算机编程解决问题。
循环暴力枚举解决法,理论上可以,可行性不行,转换思路分解出整个数字的所有因(约)数,然后对所有的因数暴力枚举两重循环,计算出结果。
#include
int judge(long long a,long long b,long long c)
{
if(a==b==c)//长宽高相同排列只有一种组合
return 1;
if(a==b&&a!=c||a==c&&a!=b||b==c&&a!=b) //长宽高 任意两个相同排列只有3种
return 3;
else
return 6; //长宽高都不相同排列只有6种
}
int mian()
{
long long n =2021041820210418;
long long L,W,H;
long long ans=0;
for(L=1;L*L*L<=n;L++) //l是最小的一方
{
if(n%L==0)//小优化
{
for(W=L;L*W*W<=n;W++)//l是第二大的一方,次数多
{
if(n%(L*W)==0)//小优化
{
H=n/L/W;
if(H>=W){
ans+=judge(L,W,H);
}
}
}
}
}
printf("%d",ans);
}
结果:2430