算法趣题-Q35

一、问题描述

二、问题分析

        很明显,此题想考的就是反推思想,在正向遍历时的计算复杂度是不确定的,但一定很大,根据书中给出的答案可知确实如此,由此需要我们从结果向前进行推导,虽然根据结果反向遍历的计算复杂度同样不确定,但可以肯定的是其复杂度必然不会超过正向的,而且减少了大量的无效计算。因此,在代码实现时,我们通过生成只包含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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值