北林oj-算法设计与分析-Tom palindrome number

描述

Tom is studing math these days. If there is a number X, whose binary form and decimal form are all palindrome numbers, Tom names it "Tom palindrome number". And Tom wants to know how many "Tom palindrome number" there are between N and M ? (1001,66,64446 are all palindrome number)

输入

Each test case starts with two integer N and M (1<=N<=M<=1000000).

输出

For each test case, you must print all Tom palindrome numbers between N and M, one line for each. After each test case you must print a blank line. And print nothing if there isn't any "Tom palindrome number" between N and M.

输入样例 1

1 5
2 2
5 10
10 40

输出样例 1

1
3
5


5
7
9

33

思路及踩坑:

字符串比较肯定不行,totring方法最多能用一次,如果所有数字都用tostring转的话就超时。

reverse函数不能用,会超时,手动for循环模拟reverse也会超时,字符串基本被ban了。

——————————

思路是先自己找出来范围内所有符合要求的数,存在一个数组里,然后输出符合要求的数就行了,一次运算解决所有问题。

全局数组ans存储所有符合要求的数。

Dealing函数:看一个数是不是符合题意。这里记得先存一下原来的数字,因为每次操作数字都比原来少了一半。先在里面开辟一个辅助数组v,然后计算该数字的二进制位,把每一位都存到数组v里;

检测v数组里对称位置的两个数是不是一样的,如果不是直接返回;

tostring一下原来的数字(这里只用了一次所以可以),在str中也仿照对数组的处理方式,检测这个数的十进制形式是不是符合条件,不符合直接返回;

如果两次返回都没有被执行,就说明这个数符合条件,加到ans里;

根据输入的数字,输出ans里满足条件的数

注意,ans可以自己先调试一下看看大小以及最大的数是多少,再修改,就不用循环1000000次了。

代码如下:

#include<string>
#include<iostream>
#include<vector>
using namespace std;

vector<int> ans;
void Dealing(int x) {
	vector<int> v;//记录二进制数的每一位
	int i = 0;
	if (x == 1) {
		ans.push_back(1);
		return;
	}
	int x1 = x; //保留原始数据
	while (x) { //记录二进制数的每一位
		v.push_back(x % 2);
		x /= 2;
		i++;
	}
	for (int j = 0; j < i / 2; j++) { //不满足要求,退出
		if (v[j] != v[i - j - 1]) {
			return;
		}
	}

	string str = to_string(x1);
	int len = str.length();
	for (int i = 0; i < len / 2; i++) {//十进制比对,这里tostring可以用,不会超时
		if (str[i] != str[len - i - 1])
			return;
		else continue;
	}
	ans.push_back(x1);//如果在上面那么多比对中都没退出,说明确实是回文数,ans加进去
}
int main()
{
	for (int i = 1; i <= 585585; i++) {//为什么是585585,调试看出来的,耍点诡计
		Dealing(i);
	}
	int n, m;
	while (cin >> n >> m) {
		for (int i = 0; i < ans.size(); i++) {
			if (ans[i] >= n && ans[i] <= m) {
				cout << ans[i] << endl;
			}
			if (ans[i] > m) {
				break;
			}
		}
		cout << endl;
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值