蓝桥杯-回文数字

目录

1.题目

2.解题思路

3.代码思路

4.代码实现

5.附录


1.题目

题目描述

观察数字:12321,123321  都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的。这样的数字叫做:回文数字。 

本题要求你找到一些5位或6位的十进制数字。满足如下要求: 
该数字的各个数位之和等于输入的整数。 

输入

一个正整数 n (10< n< 100), 表示要求满足的数位和。

输出

若干行,每行包含一个满足要求的5位或6位整数。 
数字按从小到大的顺序排列。 
如果没有满足条件的,输出:-1 

样例输入

44

样例输出

99899
499994
589985
598895
679976
688886
697796
769967
778877
787787
796697
859958
868868
877778
886688
895598
949949
958859
967769
976679
985589
994499

2.解题思路

题意:题目的意思是,给出1个n,然后你给出一系列的回文数,每个回文数的各个位上的数的和等于n,而回文数的范围为1e5到1e6。

        因为回文数的特点是从左到右和从右到左的数字是一样的,这样,一个回文数可以看做是这个回文数一半的数输出两遍(偶数),所以我们可以只枚举回文数的一半,另一半将这个回文数,调整位置再输出一次即可,这样遍历的次数会少一半。因此,枚举100到999,然后再判断一下,其各个位数加起来的和是否等于n即可。(附录进行简单枚举,推测其合理性)

3.代码思路

g1:当前数百位上的数

g2:当前数十位上的数

g3:当前数个位上的数

输入n后,从100枚举到999,将其各个位分离,一些重复位乘2再相加判断是否等于n,等于n则将其对应位输出(5位数和6位数处理方法相近)

4.代码实现

#include<iostream>

using namespace std;
int flag;
int main()
{
    int n;
    cin >>n;
    int g1,g2,g3;
    for(int i=100;i<=999;i++)
    {
        g1=i%10;
        g2=(i/10)%10;
        g3=i/100;
        if(g1+2*g2+2*g3==n) flag=1,cout <<g3 <<g2 <<g1 <<g2 <<g3 <<endl;
    }
    for(int i=100;i<=999;i++)
    {
        g1=i%10;
        g2=(i/10)%10;
        g3=i/100;
        if(2*g1+2*g2+2*g3==n)   flag=1,cout <<g3 <<g2 <<g1 <<g1 <<g2 <<g3 <<endl;
    }
    if(flag!=1) cout <<-1;
    return 0;
}

5.附录

枚举100到109,110到119,120到129

10001

10101

10201

...

10901

11011

11111

11211

...

11911

12021

12121

12221

...

12921

通过,观察发现从1_0到1_9进行枚举,对应1_0_1到1_9_1

而若从10000枚举至12999的回文数,则有

10001

10101

10201

...

10901

11011

11111

11211

...

11911

12021

12121

12221

...

12921

观察发现,其实这两种枚举所得到的回文数相同,因为回文数的特性,其左边第n位确定,右边也同样确定,所以这题解中这种方式枚举5位数的回文数是可行的(6位数同理)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值