• 蓝桥杯 枚举算法 (c++)


    在这里插入图片描述

    枚举就是根据提出的问题,——列出该问题的所有可能的解,并在逐一列出的过程中,检验每个可能解是否是问题的真正解,
    如果是就采纳这个解,如果不是就继续判断下一个。
    枚举法一般比较直观,容易理解,但由于要检查所有的可能解,因此运行效率较低。
    能够用枚举法解决的题目往往是最简单的一类题目。这种题具有以下特点:
    ·解枚举范围是有穷的。
    ·检验条件是确定的。

    先来看一个简单的问题。
    某君说:“我的年龄是个两位数,我比儿子大27岁,如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄”
    请你计算:某君的年龄一共有多少种可能情况?
    我们来分析一下这道题。题里给出某君的年龄是两位数,那么年龄的取值范围是[10,99]内的整数。
    检验条件也是确定的,只要把枚举的年龄的个位与十位交换,如果发现比原数字刚好小27,那么它就是真正的解。
    以上的解决思路就是枚举法的一个例子。

    #include
    using namespace std;
    int main(){
    	int total=0;//记录可能解的个数 
    	for(int i=10;i<=99;i++){//枚举年龄范围 
    		if(i=(i%10)*10+i/10+27){
    			total++;}
    	}
    	cout<<total<<endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    在判断条件中,我们通过对10取模的方式来获取一个数的个位数。用除10的方法来获取一个数的十位数。(在程序中整型数字与整型数字相除表示整除,所以除10会让数字的个位数字被舍去,其余的十进制每一位向右移动一位。)
    这道题是第七届蓝桥杯C/C++语言A组的题目。

    前面的课程里,我们已经学习了如何输出1到100
    范围内的所有质数。接下来,我们要实现输出n到m之间所有质数的程序。n,m保证为正整数。
    首先,我们肯定需要定义并读入两个整数n,m,把

    int n;
    
    • 1

    修改为:

    int n,n;
    cin>>n>>m;
    
    • 1
    • 2

    并将外层循环结构改为

    for(int j=n;j<=m;j++){
    
    }
    
    • 1
    • 2
    • 3
    #include
    using namespace std;
    int main(){
    	int n,m;
    	cin>>n>>m;
    	for(int j=n;j<=m;j++){
    			if(j==1){
    				continue;
    			}
    		bool is_prime=true;
    		for(int i=2;i<j;i++){
    			if(j%i==0){
    				is_prime=false;
    				break;
    			}
    		}
    		if(is_prime){
    			cout<<j<<endl;
    		}
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    观察数字:12321,123321都有一个共同的特征,就是无论从左到右读还是从右向左读,都是相同的。这样的数字叫做回文数字。
    现在要从5位或6位的十进制数字中找出各个数位之和等于n的回文数字。
    输入格式
    输入一个整数n(10≤n≤100)。
    输出格式
    输出所有各个数位之和等于n的5位和6位整数,每个数字占一行,
    数字按从小到大的顺序排列。如果没有满足条件的数字,则输出-1.
    样例输入

    48
    
    • 1

    样例输出

    699996
    789987
    798897
    879978
    888888
    897798
    969969
    978879
    987789
    996699
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    #include
    using namespace std;
    int n;
    int digit[6];
    bool judge(int x){
    	int m=0,sum=0;
    	while(x){
    		digit[m++]=x%10;
    		sum+=x%10;
    		x/=10;
    	}
    	if(sum!=n){
    		return false;
    	}
    	for(int i=0;i<m/2;i++){
    		if(digit[i]!=digit[m-1-i]){
    			return false;
    		}
    		}
    		return true;
    	}
    	int main(){
    		bool f = false;
    		cin>>n;
    		for(int i=10000;i<1000000;i++){
    			if(judge(i)){
    				cout<<i<<endl;
    				f=true;
    			}
    		}
    		if(!f){
    			cout<<-1<<endl;
    		}
    		return 0;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    在这里插入图片描述

    如果一个4位数,它的每个位上的数字的4次幕之和等于它本身,那么我们就称这个数字为一个四叶玫瑰数。现在,我们要求出n以内所有的四叶玫瑰数。
    首先,我们读入了一个整数n,由于四叶玫瑰数一定是个四位数,那我们首先将其它位数的数字排除,请在return 0;之前写:

    if(n<1000||n>9999){
    	cout<<"error!";
    }else{
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    接下来,我们要依次枚举从1000开始到n之间的数字,哪些符合四叶玫瑰数的要求,并将它输出。在这里,我们将判断四叶玫瑰数的代码封装成一个自己定义的函数rose,我们先在else分支中写:

    for(int i=1000;i<=n;i++){
    	if(rose(i)){
    		cout<<i<<endl;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    输入一个四位数n,看看1000到n之间有没有四
    叶玫瑰数吧。
    ·事实上,一共有三个四叶玫瑰数,他们分别是
    1634,8208,9474

    #include
    #include
    using namespace std;
    bool rose(int i){
    	int a=i/1000,b=i/100%10,c=i/10%10,d=i%10;
    	int ans=a*a*a*a+b*b*b*b+c*c*c*c+d*d*d*d;
    	if(ans==i){
    		return true;
    	}else{
    		return false;
    	}
    }
    int main(){
    	int n;
    	cin>>n;
    	if(n<1000||n>9999){
    		cout<<"error!";
    	}else{
    		for(int i=1000;i<=n;i++){
    			if(rose(i)){
    				cout<<i<<endl;
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述
    某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。现在算起来,他一共吹熄了236根蜡烛。那么,他从几岁开始过生日party的。从常识来讲一个人的年龄不可能超过200岁。
    因此,我们需要枚举这个人的开始过生日的年龄,
    从0到200,请在return 0:之前写:

    for(int i=1;i<=200;i++){
    	
    }
    
    • 1
    • 2
    • 3

    接下来,我们需要依次枚举他从某岁到某岁之间会吹多少蜡烛。如果这个数目超过236,我们就不关心了;同时,我们并不知道这中间过了多少岁,所以无法确定循环次数,因此这里使用while循环更合适,请在for循环中写:

    int can=0,j=i;
    while(can<236&&j<=200){
    	can+=j;
    	j++;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    其中,变量can用于记录蜡烛数目,j是一个累加变量。

    跳出while循环后,如果蜡烛的数目恰好等于236
    ,说明枚举条件成立,变量的值就是他开始过
    生日时的年龄。
    请接着写:

    if(can==236){
    	cout<<i<<endl;
    }
    
    • 1
    • 2
    • 3

    其中,变量can用于记录蜡烛数目,j是一个累加变量。
    运行一下,看看结果是不是26。
    想一想,如果我们还想知道他今年多少岁,应该怎
    么做呢?

    #include
    using namespace std;
    int main(){
    	for(int i=1;i<=200;i++){
    		int can=0,j=i;
    		while(can<236&&j<=200){
    			can+=j;
    			j++;
    		}
    		if(can==236){
    			cout<<i<<endl;
    		}
    	}
    	return 0;
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述
    有些人很迷信数字,比如认为带4的数不吉利。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的
    号码,主办方想让你计算一下,如果发行号码n到m之间的奖券,在任何两张奖券都不重复的情况下,可以发行多少张?
    输入格式
    输入为一行,为两个空格隔开的整数n,m,
    10000 <=n <=m <=99999.
    输出格式
    输出为一个整数,为可发出奖券的数目。
    样例输入

    10000 99999
    
    • 1

    样例输出

    52488
    
    • 1
    #include
    using namespace std;
    bool judge(int x){
    	while(x){
    		if(x%10==5){
    			return true;
    		}
    		x/=10;
    	}
    	return false;
    }
    int main(){
    	int n,m,cnt=0;
    	cin>>n>>m;
    	for(int i=n;i<=m;i++){
    		if(!judge(i)){
    			cnt++;
    		}
    	}
    	cout<<cnt<<endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

  • 相关阅读:
    SSH远程登录网络设备
    聊聊Tomcat架构和生命周期
    06 Thread API
    Mobpush上线跨时区推送功能,助力中国开发者应用出海
    B2B独立站怎样将客户转化为订阅会员
    斐波那契数列,剑指offer,力扣
    学习C++第二十课--对象移动、移动构造函数与移动赋值运算符笔记
    【23期】你知道Java面向对象设计的六大原则吗
    DeltaLake技术学习与总结待续
    SpringMVC
  • 原文地址:https://blog.csdn.net/weixin_74774974/article/details/133777633