枚举问题归纳

例题1 abc(清华大学复试上机题)

题目描述:

设a、b、c均是0到9之间的数字,abc、bcc是两个三位数,且有:abc+bcc=532。求满足条件的所有a、b、c的值。

输入描述:

题目没有任何输入。

输出描述:

请输出所有满足题目条件的a、b、c的值。 a、b、c之间用空格隔开。 每个输出占一行。

代码内容:
#include <cstdio>
int main() {
    int a,b,c;
    for(a=0; a<=9; ++a){
        for(b=0 ; b<=9; ++b) {
            for(c=0; c<=9; c++){
                //abc + bcc = 532
                if(100*a+10*b+c + 100*b+10*c+c == 532){
                    printf("%d %d %d\n",a,b,c);
                    //%d是占位符 d是decimal 十进制整数
                }
            }
        }
    }
}
分析:

三位数的每一位都是0-9,因此面对这种固定范围的枚举问题,设计循环时就可直接嵌套for循环

例题2 反序数(清华大学复试上机题)

题目描述:

设N是一个四位数,它的9倍恰好是其反序数(例如:1234的反序数是4321),求N的值。

输入描述:

程序无任何输入数据。

输出描述:

输出题目要求的四位数,如果结果有多组,则每组结果之间以回车隔开。

代码内容:
//求逆序数
int Reverse(int n){
    int remain;//每次的余数
    int reverse = 0;
    while (true){
        remain = n%10;
        reverse = reverse*10 + remain;
        n = n/10;
        if(0 == n){
            break;
        }
    }
    return reverse;
}

//逆序数是其9倍
int main(){
    int a,b,c,d;
    for(a=1; a<=9; ++a){
        for(b=0; b<=9; ++b){
            for(c=0; c<=9; ++c){
                for(d=0; d<=9; ++d){
                    int n = 1000*a + 100*b + 10*c + d;
                    if(n*9 == Reverse(n)){
                        printf("%d\n", n);
                    }
                }
            }
        }
    }
}
分析:
步骤(每次/10)   得到每一位    计算结果
1234 % 10  ——>   4   ——>   4
123  % 10  ——>   3   ——>   4*10 + 3
12   % 10  ——>   2   ——>   43*10 + 2
1    % 10  ——>   1   ——>   432*10 + 1

我们可以发现给定一个四位数n,我们可以对其求余找到个位,然后每次进行/10操作,这样能够单独取到每一位,我们可以用变量reverse保存上一次结果,然后不断*10再加上每次的余数remain。最后n等于0时退出循环。

因此面对这种不固定范围的枚举问题,设计循环时使用while循环,要通过分析找到循环出口。

死循环问题:
    while (true){
        remain = n%10;
        reverse = reverse*10 + remain;
        n = n/10;
        if(n = 0){ // 0是假,不会执行break,循环会一直进行下去
            break;
        }
    }

初学者往往会少打等号,出现n=0与n==0的小失误,因此我们判等时可以进行这样的规范:0==n

例题3 对称平方数(清华大学复试上机题)

题目描述:

打印所有不超过256,其平方具有对称性质的数。如2,11就是这样的数,因为2*2=4,11*11=121。

输入描述:

无任何输入数据

输出描述:

输出具有题目要求的性质的数。如果输出数据不止一组,各组数据之间以回车隔开。

代码内容:
#include <cstdio>

//求逆序数
int Reverse(int n){
    int remain;//每次的余数
    int reverse = 0;
    while (true){
        remain = n%10;
        reverse = reverse*10 + remain;
        n = n/10;
        if(0 == n){
            break;
        }
    }
    return reverse;
}

//对称平方数
int main(){
    int i = 0;
    for(i = 0; i<=256; i++){
        if(i*i == Reverse(i*i)){
            printf("%d\n", i);
        }
    }
}
分析:

不难发现,其平方具有对称性质的数,即逆序数等于它本身,因此这题仅是上一题的变式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~許諾~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值