一、问题描述
二、问题分析
很明显,此题想考的就是反推思想,在正向遍历时的计算复杂度是不确定的,但一定很大,根据书中给出的答案可知确实如此,由此需要我们从结果向前进行推导,虽然根据结果反向遍历的计算复杂度同样不确定,但可以肯定的是其复杂度必然不会超过正向的,而且减少了大量的无效计算。因此,在代码实现时,我们通过生成只包含0和7的序列反向验证以得到结果。
三、代码实现
1.C/C++实现
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cctype>
using namespace std;
// 获取只包含0,7的十进制数
int get_num(int num)
{
int tmp = 0, bits = 1;
while (num)
{
if (num % 2)
tmp += 1 * bits;
num /= 2;
bits *= 10;
}
return tmp * 7;
}
// 判断是否是回文序列
bool judge(int num)
{
vector<char> list;
while (num)
{
list.push_back(num % 10 + '0');
num /= 10;
}
for (int i = 0; i < list.size() / 2; i++)
if (list[i] != list[list.size() - 1 - i])
return false;
return true;
}
int main()
{
int flags[50];
memset(flags, 0, sizeof(flags));
flags[0] = 1;
int left = 49, num = 1;
while (left)
{
int tmp = get_num(num++);
for (int i = 1; i < 50; i++)
{
if (flags[i])
continue;
if (i % 2 == 0 or i % 5 == 0)
{
flags[i] = 1;
left--;
}
else if (tmp % i == 0)
{
flags[i] = 1;
left--;
if (judge(tmp))
cout << i << endl;
}
}
}
return 0;
}
2.Python实现
# codiNg = utf-8
def get_next_num():
"""
生成只包含0和7的十进制数
:return: int
"""
num = 0
while True:
num += 1
tmp = bin(num)[2:]
yield 7 * int(tmp)
def get_answer():
answer = set()
flags = [1, 0] * 25
for i in get_next_num():
for j in range(1, 50, 2):
if flags[j]:
continue
# 2 和 5 的倍数不可能产生目标类型数
if j % 5 == 0:
flags[j] = 1
continue
elif i % j == 0:
flags[j] = 1
if str(i) == str(i)[::-1]: # 是回文序列
answer.add(j)
if sum(flags) == 50:
break
return tuple(sorted(answer))
if __name__ == '__main__':
print(get_answer())
pass