21位水仙花数
2012-03-12 20:36
323 查看
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