老兔新传IT版

穷困潦倒的IT公司职员的故事

  博客园 :: :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

这天正感无趣,树杈(一哥们儿)发来一个妖题,Google了一下,发现自己孤陋了。随手回了个话,建议他写个程序算算看。几天后见面时,那厮果然写程序算了,据说程序跑了一个下午没有把结果搞出来。听说另外还有一玩VB的兄弟算到程序崩溃也没看到答案。遂兴趣大起,和树杈一下探讨了一下算法,下面是一个效率尚可的解决办法,更高效算法尚在思考中(只是树杈在思考,我已经放弃动脑了,好累啊)。

 1#!/usr/bin/python
 2#coding: utf8
 3'''
 4Created on 2009-6-1
 5@author: sutra
 6
 7求满足下列条件的数:
 81、它是一个质数;
 92、它的各位数字必须是递减的;
103、把它的数字逆转过来,得到各位递增的数字,仍然是个质数;
114、它是满足以上三个条件的数字中最大的一个。
12'''
13
14'''
15删除数位求解法
16'''
17import string
18import math
19
20# 判断一个数是否是素数
21def isprime(prime):
22    i=2
23    limit=int(math.sqrt(prime))
24    for i in range(2,limit+1):
25        if prime % i == 0:
26            return False
27        i=i+1
28    return True
29
30# 从数 a 中删除一位。
31def delete(a, arr):
32    s = str(a)
33    l = len(s)
34
35    for j in range(0, l):
36        b = (a / (10 ** (j + 1)) * (10 ** j)) + (a - a / (10 ** j) * (10 ** j))
37        arr.append(b)
38
39if __name__ == '__main__':
40    # 素数末位不能是0,并且又要递减,所以这里没有0
41    a = 987654321
42    fromarr = [a]
43    toarr = [a]
44    result = []
45
46    l = len(str(a))
47
48    for i in range(1, l):
49        for a in fromarr:
50            delete(a, toarr)
51            result.extend(toarr)
52            fromarr = list(set(toarr))
53
54    result = list(set(result))
55    result.sort()
56    #print result
57
58    prime = []
59    for b in result:
60        if isprime(b) and isprime(int(str(b)[::-1])):
61            prime.append(b)
62
63    prime.sort()
64    print prime[len(prime) - 1]
65

 

思路比较简单:

1、因为是一个从高位到低位递减的数字,所以最大的一个符合条件的数字是9876543210。
2、以零结尾的数不可能是质数, 所以最大就变成了987654321,一共9位。
3、由于在一个顺序序列中任意删除一个或多个单元,该序列仍然有序,所以我们采用删位的方法来循环。(其实这里应该写个递归,树杈这人太懒了,懒的都快和我看齐了)
4、先看9位的数是否符合要求,如果不符合就从低位到高位穷举删掉1位的状况,看看有没有符合的,如果还没有就在删掉1位的数字的基础上再删掉1位……(明显就是递归嘛)
5、第一个遇到的符合条件的数字就是最大的符合条件的数,答案就是9875321,这个不包含任何政治意义的数字。

这里仅仅解释一下36行那个表达式,这个可读性极低的表达式绝对是偷懒的结果。
其实就像注释所说,希望从一个数字中删掉其中的某1位得到另一个数,我们觉得数学运算应该要比字符串运算要更快,所以写了这个表达式。
其原理很简单,假设要抽调十位上的数字,就把百位以上的数字用整除除出来然后乘以10再加上各位的数字就成了。

今天听说有一个可以提高质数检查效率的算法,持续关注中。

posted on 2009-06-03 18:12  老兔  阅读(1269)  评论(0编辑  收藏  举报