# python3京东神奇数

https://blog.csdn.net/bing_lee/article/details/77899602

1 主要目的，找出该数中各个位上的数组成的集合M中是否存在某个组合K使得sum(K)== sum(M)/2

2 当M中的最大值max(M) > sum(M)/2时，则该数不可能为神奇数，如1119

3 从M的第一个元素开始，递归寻找目标组合K，对于不可能的组合及时剪枝，避免冗余的递归计算

4 每次递归浅复制M的子集M'，并去除当前选中的元素

5 找到sum(K)== sum(M)/2的组合K则返回True

6 当M'中元素个数为0，时返回False

import time
def run(a,b):
sum = 0
for i in range(a,b):
if check(i):
sum += 1
return  sum

def num2array(n):
n_str = str(n)
length = len(n_str)
arr = []
for i in range(length):
arr.append(int(n_str[i]))
arr.sort()
return arr

def check(n):
n_arr = num2array(n)
a = sum(n_arr)
# 偶数才有可能成为神奇数
if a % 2 == 0:
half = int(a / 2)
max_item = max(n_arr)
if max_item > half:
return False
else:
if max_item == half:
return True
else:
return  handler(n_arr,0,half)

def handler(arr,sum,half):
length = len(arr)
if length == 0:
return False
for k in arr:
tmp_sum = sum + k
if tmp_sum == half:
return True
else:
if tmp_sum > half:
continue
else:
arr1 = arr[:]
arr1.remove(k)
if handler(arr1,tmp_sum,half):
return True

a = 1
b = 65535
start = time.time()
sum = run(a,b)
end = time.time()
print('共有：%d 个神奇数,检测耗时%.2f s' % (sum,end-start))

python不愧为胶水语言，功能强大，速度较慢，要想达到京东要求的1s执行，估计用C/C++会好一点

import time

class MagicNumber:

__dict = {}

def run(self,a,b):
sum = 0
for i in range(a,b):
if self.check(i):
sum += 1
# print(i)
return  sum

def num2array(self,n):
n_str = str(n)
length = len(n_str)
arr = []
for i in range(length):
arr.append(int(n_str[i]))
arr.sort()
return arr

def check(self,n):
n_arr = self.num2array(n)
a = sum(n_arr)
# 偶数才有肯能成为神奇数
if a % 2 == 0:
half = int(a / 2)
max_item = max(n_arr)
if max_item > half:
return False
else:
key = self.array2string(n_arr)
if key in self.__dict:
return  True
if max_item == half:
self.__dict[key] = 1
return True
else:
re = self.handler(n_arr,0,half)
if re:
self.__dict[key] = 1
return  re

def array2string(self,arr):
string = ''
for i in arr:
string += str(i)
return  string

def handler(self,arr,sum,half):
# 最后还么没有满足
length = len(arr)
if length == 0:
return False
for k in arr:
tmp_sum = sum + k
if tmp_sum == half:
return True
else:
if tmp_sum > half:
continue
else:
arr1 = arr[:]
arr1.remove(k)
if self.handler(arr1,tmp_sum,half):
return True

def get_dict(self):
return self.__dict

a = 1
b = 1000000
start = time.time()
c = MagicNumber()
sum = c.run(a,b)
end = time.time()
print('共有：%d 个神奇数,检测耗时%.2f s' % (sum,end-start))


65535条数据检查时间还提高了

100w个数检查了20s，不知道哪位大佬能给个C的运行时间

PS 本人电脑配置