算法趣题(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/TuringGo/article/details/82898814

1. 回文十进制数

问题描述:求十进制、二进制、八进制表示都是回文数的所有数字中,大于10的最小数值。例如:9(十进制数)= 1001(二进制数)= 11(八进制数),这样的数字,但要找到一个大于10的最小的符合规则的数字。

分析

  • 因为二进制数字不能以0开头,所以二进制数字首位必定是数字1,根据回文数的特点可推知,二进制数最低位也必须是1。因此最低位是1的二进制数,必定是一个奇数,继而可以排除所有的偶数可能性。

算法

  • 从大于10的最小的奇数——11开始遍历
  • 先判断十进制是否是回文数,再去判断二进制和十六进制是否符合
  • 由于不确定搜索范围的上限(虽然可以定义是int最大值),所以应该用while True来达到不断循环的目的,直到找到第一个三种进制都满足回文数,当前数字就是大于10的最小的回文数,跳出循环

Python代码实现

def palind_num():
    num = 11
    while True:
        """
        1. Python中的二进制与八进制都是有前缀的,由于前缀的存在,所以一旦翻转,需要删除前缀字段才能比较相同
        2. 使用切片将字符串翻转
        """
        if str(num) == str(num)[::-1] and bin(num).strip('0b') == bin(num)[::-1].strip('b0') and oct(num).strip('0o') == oct(num)[::-1].strip('o0'):
            break
        else:
            num += 2
    return num

result = palind_num()
print("十进制:", result)
print("二进制:", bin(result).strip('0b'))
print("八进制:", oct(result).strip('0o'))

# 十进制: 585
# 二进制: 1001001001
# 八进制: 1111

2. 数列的四则运算

问题描述:将一个十进制四位数的每一位数字,按照原来的顺序进行加减乘除运算至少一次,使得其结果为原数字的倒序,求范围在1000 ~ 9999内满足要求的数字。例如:1314:1 * 3 + 14 = 17,或1314:131 * 4 = 524这样的组合,直到满足存在一组运算,使得1、3、1、4这四个数字的计算结果为4131。

分析

  • 很显然,对于一个四位数而言,若要满足其结果为原来的倒序的组成的数字,就意味着倒序的结果必定是一个四位数字。
  • 对于任何一个四位数而言,一旦出现减法和除法,这种会减少原来值的运算,肯定不可能得出新的四位数。同样的,对于加法亦是如此,因此加法在四位数与四则运算组合中,最大的可能情况是 999 + 9 = 1008,1008虽然是个四位数,但明显与范围内最大值不同。综上,只有乘法运算,才可能找到符合要求的数字。

算法

  • 遍历1000 ~ 10000之间的所有四位数
  • 使用空字符串 ‘’ ,来实现将组合不同长度的数字,例如:1314:‘1’ + ‘’ + ‘2’ + ‘*’ + ‘3’ + ‘’ + ‘4’ = ‘12 * 34’
  • eval函数中,不允许出现数字前面带0的操作数,例如:eval(“1*001”),会报错!因此,对于每个单独的数字字符串前面的0,需要删除掉!采用,函数**lstrip(‘0’)**达到删除每个数字字符串前的0
  • 所有组合中,若最后一位数字是0,那么依据上一步算法,会将0删去。这就意味着出现数字后面带有乘号的字符串,例如:[‘7*’, ‘’, '5’, ‘’]组合的字符串就是 ‘75 *’,而eval(‘75 *’)操作是非法的!所有,必须删除所有数字字符串后面的乘号,用函数 *rstrip(’ ') 来删除
  • 所有组合中,可能会出现这样的情况:[‘7*’, ’ *’, ’ *’, ‘1’],当数字之间含有两个乘号时,这是一个幂乘运算,不是乘法运算。所以,只能保留一个乘号,用函数 replace() 变换成乘法运算
  • 为了防止出现这样的情况:[‘5’, ‘7’, ‘7’, ‘5’] 5775,即四个数字中没有加入运算符,因此,需要判断字符串的长度至少大于4位,即至少插入一个运算符

Python代码实现

opera = ['*', '']
for n in range(1000, 10000):
    num = str(n)
    for i in opera:
        for j in opera:
            for k in opera:
                num2 = num[0] + i + ' ' + num[1] + j + ' ' + num[2] + k + ' ' + num[3]
                num3 = [s.lstrip('0') for s in num2.split(' ')]
                num4 = ''.join(num3).rstrip('*').replace('**', '*')
                if len(num4) > 4:
                    if str(n)[::-1] == str(eval(num4)):
                        print(num3, num4, n)
                    
# ['5*', '9*', '3', '1']
# 5*9*31
# 5931

猜你喜欢

转载自blog.csdn.net/TuringGo/article/details/82898814