21位水仙花数

class WaterNum(object):
	"""
	"""
	def __init__(self,N = 21):
		"""
		"""
		self.N			= N
		self.sum		= 0
		self.p_remain	= N
		self.pre_table	= []
		self.max_num	= pow(10,N) - 1
		self.min_num	= pow(10,N - 1)
		self.count		= [-1 for i in range(10)]
		self.filter		= [0 for i in range(10)]

		self.init_pre_table()
		#print('pre_table:\n',self.pre_table)
	
	def init_pre_table(self):
		""" initialize the pre_table
		"""
		for i in range(10):
			powi = pow(i,self.N)
			a = [val * powi for val in range(self.N + 1)]
			self.pre_table.append(a)
	
	def set_filter(self):
		"""
		"""
		k = self.k - 1
		s_str = str(self.sum)
		c = self.p_remain
		#print('c',c,'k',k)
		self.filter = [0 for i in range(10)]
		while self.max_num - self.sum < self.pre_table[k][c]:
			c -= 1
		
		if c == 0:
			return False
		temp_sum = self.sum + self.pre_table[k][c]
		temp_sum_str = str(temp_sum)

		pos = 0
		while pos < len(s_str) and s_str[pos] == temp_sum_str[pos]:
			pos += 1

		sub_str = s_str[:pos]

		for ch in sub_str:
			self.filter[int(ch)] += 1
		#print('sum:',s_str,'temp_sum:',temp_sum_str,'c:',c)
		#print('sub_str:',sub_str)

		return True

	def is_sum_ok(self):
		"""
		"""
		for i in range(self.k,10):
			if self.filter[i] > self.count[i]:
				return False

		return True

	def print_right(self,sum):
		""" test the sum is the value we want
		if yes print it ,if no ,do thing
		"""
		s_str = str(sum)
		count_temp = [0 for i in range(10)]
		for ch in s_str:
			count_temp[int(ch)] += 1
		for i in range(10):
			num_temp = self.count[i]
			# if is -1,turn to 0
			if num_temp < 0:
				num_temp = 0
			if num_temp != count_temp[i]:
				return False
		print('found:',s_str)
		return True

	def trace_back(self):
		"""
		"""
		self.count[self.k] = -1
		self.k += 1
		self.freq = 0


	def search(self):
		"""
		"""
		self.k = 9
		self.freq = 1
		while self.k < 10:
			if self.freq == 0:
				self.freq = 1
				self.count[self.k] += 1
			else:
				if self.freq > self.p_remain:
					self.trace_back()
					continue

				self.count[self.k] = self.freq
			if self.count[self.k] > 0:
				self.p_remain -= self.freq
				temp_sum = self.sum + self.pre_table[self.k][self.freq]
				#print('at 1')
				#print('count',self.count,'temp_sum:',temp_sum,'p_remain',self.p_remain,'k:',self.k)		
				if self.p_remain <= 0 or self.k <= 0:
					self.print_right(temp_sum)
					c = self.count[self.k] - self.freq
					self.sum -= self.pre_table[self.k][c]
					self.p_remain += self.count[self.k]
					self.trace_back()
					#print('at 1-1')
					continue
				else:
					#print('at 1-2')
					if temp_sum > self.max_num:
						c = self.count[self.k] - self.freq
						self.sum -= self.pre_table[self.k][c]
						self.p_remain += self.count[self.k]
						self.trace_back()
						#print('at 1-3')
						continue
					self.sum = temp_sum
				if self.set_filter() == True and self.is_sum_ok() == False:
					#print('at 1-4')
					self.freq = 0
					continue
				else:
					#print('at 1-5')
					self.k -= 1
					self.freq = self.filter[self.k]
					self.count[self.k] = -1
			else:
				#print('at 2')
				#print('count',self.count,'sum:',self.sum,'p_remain',self.p_remain,'k:',self.k)		
				if self.set_filter() == True and self.is_sum_ok() == False:
					self.freq = 0
					#print('at 2-1')
					continue
				self.k -= 1
				self.freq = self.filter[self.k]
				self.count[self.k] = -1
				#print('at 2-2,filter:',self.filter,'freq(',self.k,')',self.freq)

import time

if __name__ == '__main__':
	#time_begin = time.time()
	for i in range(11,39):
		print('found---------------',i,'------------------------')
		time.clock()
		water_num = WaterNum(i)
		water_num.search()
		#time_end = time.time()
		print('use time',int(time.clock()))
found 11 -----------------------------------------------
32164049650
32164049651
40028394225
42678290603
44708635679
49388550606
82693916578
94204591914
use time 0
found 12 -----------------------------------------------
use time 1
found 13 -----------------------------------------------
use time 1
found 14 -----------------------------------------------
28116440335967
use time 3
found 15 -----------------------------------------------
use time 6
found 16 -----------------------------------------------
4338281769391370
4338281769391371
use time 9
found 17 -----------------------------------------------
21897142587612075
35641594208964132
35875699062250035
use time 15
found 18 -----------------------------------------------
use time 23
found 19 -----------------------------------------------
1517841543307505039
3289582984443187032
4498128791164624869
4929273885928088826
use time 35
found 20 -----------------------------------------------
63105425988599693916
use time 51
found 21 -----------------------------------------------
128468643043731391252
449177399146038697307
use time 21
found 22 -----------------------------------------------
use time 54
found 23 -----------------------------------------------
21887696841122916288858
27879694893054074471405
27907865009977052567814
28361281321319229463398
35452590104031691935943
use time 94
found 24 -----------------------------------------------
174088005938065293023722
188451485447897896036875
239313664430041569350093
use time 141
found 25 -----------------------------------------------
832662335985815242605070
832662335985815242605071
1550475334214501539088894
1553242162893771850669378
3706907995955475988644380
3706907995955475988644381
4422095118095899619457938
use time 209
found 26 -----------------------------------------------
use time 305
found 27 -----------------------------------------------
77888878776432530886487094
121204998563613372405438066
121270696006801314328439376
128851796696487777842012787
174650464499531377631639254
177265453171792792366489765
use time 431
found 28 -----------------------------------------------
use time 580
found 29 -----------------------------------------------
4716716265341543230394614213
5022908050052864745436221003
14607640612971980372614873089
19008174136254279995012734740
19008174136254279995012734741
23866716435523975980390369295
use time 748
found 30 -----------------------------------------------
use time 955
found 31 -----------------------------------------------
793545620525277858657607629822
1145037275765491025924292050346
1927890457142960697580636236639
2309092682616190307509695338915
use time 1223
found 32 -----------------------------------------------
17333509997782249308725103962772
use time 1545
found 33 -----------------------------------------------
32186410459473623435614002227248
186709961001538790100634132976990
186709961001538790100634132976991
use time 1937
found 34 -----------------------------------------------
1122763285329372541592822900204593
use time 2416
found 35 -----------------------------------------------
5250083909873201044638631458484846
7673249664848285722449710136138169
12639369517103790328947807201478392
12679937780272278566303885594196922
use time 3041
found 36 -----------------------------------------------
91097771122214850683543503173498149
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值