枚举就是根据提出的问题,------列出该问题的所有可能的解,并在逐一列出的过程中,检验每个可能解是否是问题的真正解,
如果是就采纳这个解,如果不是就继续判断下一个。
枚举法一般比较直观,容易理解,但由于要检查所有的可能解,因此运行效率较低。
能够用枚举法解决的题目往往是最简单的一类题目。这种题具有以下特点:
·解枚举范围是有穷的。
·检验条件是确定的。
先来看一个简单的问题。
某君说:"我的年龄是个两位数,我比儿子大27岁,如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄"
请你计算:某君的年龄一共有多少种可能情况?
我们来分析一下这道题。题里给出某君的年龄是两位数,那么年龄的取值范围是[10,99]内的整数。
检验条件也是确定的,只要把枚举的年龄的个位与十位交换,如果发现比原数字刚好小27,那么它就是真正的解。
以上的解决思路就是枚举法的一个例子。
cpp
#include<iostream>
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;
}
在判断条件中,我们通过对10取模的方式来获取一个数的个位数。用除10的方法来获取一个数的十位数。(在程序中整型数字与整型数字相除表示整除,所以除10会让数字的个位数字被舍去,其余的十进制每一位向右移动一位。)
这道题是第七届蓝桥杯C/C++语言A组的题目。
前面的课程里,我们已经学习了如何输出1到100
范围内的所有质数。接下来,我们要实现输出n到m之间所有质数的程序。n,m保证为正整数。
首先,我们肯定需要定义并读入两个整数n,m,把
cpp
int n;
修改为:
cpp
int n,n;
cin>>n>>m;
并将外层循环结构改为
cpp
for(int j=n;j<=m;j++){
}
cpp
#include<iostream>
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;
}
观察数字:12321,123321都有一个共同的特征,就是无论从左到右读还是从右向左读,都是相同的。这样的数字叫做回文数字。
现在要从5位或6位的十进制数字中找出各个数位之和等于n的回文数字。
输入格式
输入一个整数n(10≤n≤100)。
输出格式
输出所有各个数位之和等于n的5位和6位整数,每个数字占一行,
数字按从小到大的顺序排列。如果没有满足条件的数字,则输出-1.
样例输入
cpp
48
样例输出
cpp
699996
789987
798897
879978
888888
897798
969969
978879
987789
996699
cpp
#include<iostream>
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;
}
如果一个4位数,它的每个位上的数字的4次幕之和等于它本身,那么我们就称这个数字为一个四叶玫瑰数。现在,我们要求出n以内所有的四叶玫瑰数。
首先,我们读入了一个整数n,由于四叶玫瑰数一定是个四位数,那我们首先将其它位数的数字排除,请在return 0;之前写:
cpp
if(n<1000||n>9999){
cout<<"error!";
}else{
}
接下来,我们要依次枚举从1000开始到n之间的数字,哪些符合四叶玫瑰数的要求,并将它输出。在这里,我们将判断四叶玫瑰数的代码封装成一个自己定义的函数rose,我们先在else分支中写:
cpp
for(int i=1000;i<=n;i++){
if(rose(i)){
cout<<i<<endl;
}
}
输入一个四位数n,看看1000到n之间有没有四
叶玫瑰数吧。
·事实上,一共有三个四叶玫瑰数,他们分别是
1634,8208,9474
cpp
#include<iostream>
#include<cmath>
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;
}
}
}
}
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。现在算起来,他一共吹熄了236根蜡烛。那么,他从几岁开始过生日party的。从常识来讲一个人的年龄不可能超过200岁。
因此,我们需要枚举这个人的开始过生日的年龄,
从0到200,请在return 0:之前写:
cpp
for(int i=1;i<=200;i++){
}
接下来,我们需要依次枚举他从某岁到某岁之间会吹多少蜡烛。如果这个数目超过236,我们就不关心了;同时,我们并不知道这中间过了多少岁,所以无法确定循环次数,因此这里使用while循环更合适,请在for循环中写:
cpp
int can=0,j=i;
while(can<236&&j<=200){
can+=j;
j++;
}
其中,变量can用于记录蜡烛数目,j是一个累加变量。
跳出while循环后,如果蜡烛的数目恰好等于236
,说明枚举条件成立,变量的值就是他开始过
生日时的年龄。
请接着写:
cpp
if(can==236){
cout<<i<<endl;
}
其中,变量can用于记录蜡烛数目,j是一个累加变量。
运行一下,看看结果是不是26。
想一想,如果我们还想知道他今年多少岁,应该怎
么做呢?
cpp
#include<iostream>
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;
}
有些人很迷信数字,比如认为带4的数不吉利。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带"4"的
号码,主办方想让你计算一下,如果发行号码n到m之间的奖券,在任何两张奖券都不重复的情况下,可以发行多少张?
输入格式
输入为一行,为两个空格隔开的整数n,m,
10000 <=n <=m <=99999.
输出格式
输出为一个整数,为可发出奖券的数目。
样例输入
cpp
10000 99999
样例输出
cpp
52488
cpp
#include<iostream>
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;
}