C++ 判断一个数是否为回文 / 获取整数的某一位数字

C++ 判断一个数是否为回文 / 获取整数的某一位数字


》概述

原题是蓝桥杯的基础训练题:

问题描述
  123321是一个非常特殊的数,它从左边读和从右边读是一样的。
  输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。
输入格式
  输入一行,包含一个正整数n。
输出格式
  按从小到大的顺序输出满足条件的整数,每个整数占一行。
样例输入
52
样例输出
899998
989989
998899

有题可知,求整数 x,10000(五位数) <= x < 1000000(七位数),且 x 各位数的和等于 n。
首先要求回文,比对 x 的 第 i 位 和 第 len-i-1 位是否相等。(遍历时,i 从0开始,到 len / 2)
所以如何获取整数的第 i 位是多少呢?
while循环求余 我认为有点麻烦 ( 主要是想搞点不一样的。

》获取整数的第 i 位数字

正常求法(取余):
int getCellByMod(int num, int i){	// 获取倒数第 i 位
	for(int j=0; j < i; j++){
		num /= 10;
	}
	return num % 10;
	// 很好理解, 一直 除10,直到想要的那位数处在末位上, 接着 取余获取末位上的数即可
}
我的想法:

对于一个数num = 114514,如果想获取它的最后一位数 4 (即第0位数),
得到计算方式:4 = num - num/10 *10.
num/10 意味着值为 11451, 舍弃最后一位, 再 * 10, 值为 114510, 相较于num最后一位数归 0,
接着再用 num - 114510, 就可以得到 最后一位数 4.

同理,但又有点不同的是,对于 第 i 位数 ( 0 , len - 1 ] , 即不包含第 0 位数,
计算方式为:num / pow(10, i) - num / pow(10, i+1) *10;

注: pow() 为 C++ Math库中用于计算次方的函数,参数 10 为底数, i 为指数,pow(10, 2)的结果为100.00
(返回浮点数).

例如我想求第 2 位数 5, num / pow(10, i) 的结果是 1145。 num / pow(10, i+1) *10 的结果是 1140。
则结果为 1145 - 1140 = 5。

代码 表述,有细微不同:

int getCell(int num, int i){	// 获取倒数第 i 位
	if (i==0)	return num - num / 10 * 10;
	
	return num/pow(10,i) - int(num/pow(10, i+1)) *10; 	// 取int()的原因是pow()函数返回浮点数
} 

一开始只是想搞点不一样,但开始写这篇文章的时候就开始考虑效率的问题了,稍微搜索了一下,发现对于 %(取余) 操作, 编译器会有一定的优化,而通用的优化方式和我的想法差不多嘿嘿,唯一的缺点是我的代码使用了pow()函数用于乘10的操作,这个效率可能会下降。
在这里插入图片描述
详情链接

》判断是否为回文 以及 判断各位数的和

整体思路:

  1. 获取用户输入 n,
  2. 开始大循环 遍历所有的五位数和六位数,
  3. 判断是否为回文。for循环,获取第 i 位和 len-i-1 位,进行对比,只要有一次对比不成功直接跳出,然后判断下一个数。
  4. 若此数为回文, 再次获取各位数的和, 判断是否等于 用户输入 n,若相等,打印出来。

完整代码:

#include<bits/stdc++.h>

int getCell(int num, int i){	//获取倒数第i位
	if (i==0)	return num - num/10*10;
	return num/pow(10,i) - int(num/pow(10, i+1)) *10; 
} 

int main(){
	int n, i, j, z, add, len;
	bool isHuiwen;
	scanf("%d", &n);
	for(i=10000; i<1000000; i++){
		if(i<100000) len=5;	// 判断是五位数还是六位数,方便后续遍历
		else len=6;
		isHuiwen = true; 
		for(j=len-1; j>=len/2; j--){	// 从最大数开始遍历,(也可以从0开始)
			if(getCell(i, j) == getCell(i, len-j-1))	// 判断是否相等
			{}	// 此处确实没代码,防止出错,就不改了
			else{
				isHuiwen = false; 
				break;
			}
		}
		if (!isHuiwen)
		{}	// 此处确实没代码,防止出错,就不改了
		else{
			add = 0;
			for(z=0; z<len; z++){
				add += getCell(i, z);
			}
			if (add == n)
				printf("%d\n", i);
		} 
	}
}

差不多就是这样了,有想法欢迎评论区留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值