Python 趣味百题

Posted u010019717

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 趣味百题相关的知识,希望对你有一定的参考价值。

看到这个非常好的资源, 分享一下
这些题是跟语言无关的,你可以用任何其他语言实现。

声明: 源地址 : http://www.cheemoedu.com/exercise_list/

趣味整数

1) 不重复的3位数 ->易

  1. 问题描述:
    0 ~ 9这10个数字可以组成多少不重复的3位数?
  2. 参考源码:
#coding:utf-8

# a:1-9, b:0-9, c:0-9
l = range(10)
count = 0

for a in l[1:]:
    for b in l:
        if a == b: continue #过滤a == b
        for c in l:
            if c != a and c != b: #过滤a == c, b == c
                print a, b, c
                count += 1

print ‘count:‘, count

2) 水仙花数 ->易

1.问题描述:
水仙花数是指一个n位数(n≥3),它的每个位上的数字的n次幂之和等于它本身。
例如:1 ^ 3+5 ^ 3+3 ^ 3=153。

求100 ~ 999之间所有的水仙花数。

2.参考源码:

#!/usr/bin/env python

def isArmstrongNumber(n):
    a = []
    t = n
    while t > 0:
        a.append(t % 10)
        t /= 10

    k = len(a)
    return sum([x ** k for x in a]) == n

for x in range(100, 10000):
    if isArmstrongNumber(x): 
        print x

3) 完全数 ->中

1.问题描述:
完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。例如,第一个完全数是6,它有约数1、2、3、6,除去它本身6外,其余3个数相加,1+2+3=6。第二个完全数是28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。

编程求10000以内的完全数。

2.参考源码:

#!/usr/bin/env python

def isPerfectNumber(n):
    a = 1
    b = n
    s = 0

    while a < b:
        if n % a == 0:
            s += a + b
        a += 1
        b = n / a

    if a == b and a * b == n:
        s += a

    return s - n == n

for k in range(2, 10000):
    if isPerfectNumber(k):
        print k

4) 相亲数 ->中

1.问题描述:
220的真因数之和为1+2+4+5+10+11+20+22+44+55+110=284
284的真因数之和为1+2+4+71+142=220
毕达哥拉斯把这样的数对A、B称为相亲数:A的真因数之和为B,而B的真因数之和为A。

求100000以内的相亲数。

2.参考源码:

#!/usr/bin/env python

def sumOfFactors(k):
    p = 1 
    q = k 
    s = 0 
    while p < q:
        if k % p == 0:
            s += p + q 
        p += 1
        q = k / p 

    if k == p * q and p == q:
        s += p

    return s - k 

def fun(start, end):
    for x in range(start, end):
        y = sumOfFactors(x)
        if x < y and sumOfFactors(y) == x:
            print x, y

fun(2, 100000)

5) 黑洞数 ->中

1.问题描述:
黑洞数又称陷阱数,是类具有奇特转换特性的整数。任何一个数字不全相同的整数,经有限“重排求差”操作,总会得到某一
个或一些数,这些数即为黑洞数。“重排求差”操作即把组成该数的数字重排后得到的最大数减去重排后得到的最小数。
举个例子,3位数的黑洞数为495.
简易推导过程:随便找个数,如297,3个位上的数从小到大和从大到小各排一次,为972和279,相减得693。按上面做法再做一次,得到594,再做一次,得到495,之后反复都得到495。

验证4位数的黑洞数为6174。

2.参考源码:

def fun(n):
    a = [int(c) for c in str(n)]
    a.sort()

    s1 = reduce(lambda x, y: 10 * x + y, a[::-1])
    s2 = reduce(lambda x, y: 10 * x + y, a)

    return n if s1 - s2 == n else fun(s1 - s2)

res = fun(6294)
print ‘res : ‘, res

6) 勾股数 ->易

1.问题描述:
所谓勾股数,一般是指能够构成直角三角形3条边的3个正整数(a,b,c)。
即a2+b2=c2,a,b,cΣN

求1000以内的勾股数。

2.参考源码:

import math

for a in range(1, 1000):
    for b in range(a + 1, 1000):
        c = math.sqrt(a * a + b * b)
        if c > 1000:
            break
        if c.is_integer():
            print a, b, int(c)

7) 自守数 ->易

1.问题描述:
如果某个数的平方的末尾几位等于这个数,那么就称这个数为自守数。显然,5和6是一位自守数(5 * 5=25,6 * 6=36)。 25 * 25=625,76 * 76=5776,所以25和76是两位自守数。

求10000以内的自守数。

2.参考源码:

#coding:utf-8

# 1. 计算 n 的长度 l
# 2. 取n * n的后 l 位 t 
# 3. n == t ? 

for n in range(1, 10000):
    l = len(str(n))
    t = n * n % (10 ** l)
    if t == n:
        print n
#[n for n in range(1, 10000) if n * n % (10 ** len(str(n))) == n]

8) 3位反序数 ->中

1.问题描述:
所谓反序数,即有这样成对的数,其特点是其中一个数的数字排列顺序完全颠倒过来,就变成另一个数,如102和201,36和63等,简单的理解就是顺序相反的两个数,我们把这种成对的数互称为反序数。反序数唯一不可能出现以0结尾的数。

一个3位数各位上的数字都不相同,它和它的反序数的乘积是280021,这个3位数应是多少?

2.参考源码:

# a:(1-9), b:(0-9), c:(1-9)
# a != b != c
# a < c
for b in range(10):
    for a in range(1, 10):
        if a == b: continue
        for c in range(a + 1, 10):
            if c == b: continue
            t1 = 100 * a + 10 * b + c
            t2 = 100 * c + 10 * b + a
            if t1 * t2 == 280021: print t1, t2

趣味素数

1) 素数 ->中

1.问题描述:
素数(质数)指的是不能被分解的数,除了1和它本身之外就没有其他数能够整除。

求100以内的所有素数。

2.参考源码:

def isPrimeNumber(n, s):
    for k in s:
        if k * k > n: break
        if n % k == 0: return None
    return n

prime = []
for n in range(2, 100):
    res = isPrimeNumber(n, prime)
    if res: prime.append(res)

print prime

2) 孪生素数 ->中

1.问题描述:
若两个素数之差为2,则这两个素数就是孪生素数。

编写程序找出1 ~ 100之间的所有孪生素数。

2.参考源码:

#coding:utf-8

#筛法找素数: 
# 1. 建立一张表,用True,False标识一个数是否是素数。
# 2. 找到一个素数p,然后把p的倍数都标记成非素数。
# 3. 查表检测p + 1, 如果非素数检测下一个, 是素数执行1的操作

pt = [True] * 100
res = []

for p in range(2, 100):
    if not pt[p]: continue
    res.append(p)
    for i in range(p * p, 100, p):
        pt[i] = False

for i in range(1, len(res)):
    if res[i] - res[i-1] == 2:
        print res[i-1], res[i]

3) 金蝉素数 ->中

1.问题描述:
某古寺的一块石碑上依稀刻有一些神秘的自然数。
专家研究发现:这些数是由1,3,5,7,9这5个奇数字排列组成的5位素数,同时去掉它的最高位与最低位数字后的3位数还是素数,同时去掉它的高二位与低二位数字后的一位数还是素数。因此人们把这些神秘的素数称为金蝉素数,喻意金蝉脱壳之后仍为美丽的金蝉。

试求出石碑上的金蝉素数。

2.参考源码:

#coding:utf-8

# 1. 生成 1,3,5,7,9 全排列, 每种排列是一个元组
# 2. 元组转换成数字 (例: 13579,357,159)
# 3. 检测3个数字是素数,如全是素数则是金蝉数

import math
def isPrimeNum(n):
    for k in range(2, int(math.sqrt(n) + 1)):
        if n % k == 0: 
            return False
    return True

from itertools import permutations
for p in permutations([1,3,5,7,9], 5):
    # (3,5,7), (1,5,9), (1,3,5,7,9) 
    for l in (p[1:-1], p[::2], p):
        s = reduce(lambda x, y: 10 * x + y, l)
        if not isPrimeNum(s): 
            break
    else:
        print p 

4) 可逆素数 ->中

1.问题描述:
编写程序找出1 ~ 900之间的所有可逆素数(可逆素数是指一个素数的各位数值顺序颠倒后得到的数仍为素数,如113、311)。

2.参考源码:

#coding:utf-8

# 解题步骤:
#    1. 用筛法找到900以内素数表
#    2. 迭代表内所有数,是素数的检测它的反序数是否是素数。
#    3. 2条件为真,打印这俩个素数。

def getPrimeTable(n):
    pt = [True] * n

    for p in range(2, n):
        if not pt[p]: continue
        for i in range(p * p, n, p):
            pt[i] = False

    return pt

pt = getPrimeTable(900)
for p in range(10, 900):
    if not pt[p]: continue
    q = int(str(p)[::-1])
    if p != q < 900 and pt[q]:
        pt[q] = False 
        print p, q

5) 回文素数 ->中

1.问题描述:
所谓回文素数是指,对一个整数n从左向右和从右向左读结果值相同且是素数,即称为回文素数。

求不超过1000的回文素数。

2.参考源码:

#!/usr/bin/env python

import math
def isPrimeNumber(num):
    i = 2
    x = math.sqrt(num)
    while i < x:
        if num%i == 0:
            return False
        i += 1
    return True

def Reverse(num):
    rNum = 0
    while num:
        rNum = rNum*10 + num%10
        num /= 10
    return rNum

def RPrimeNumber(num):
    arr = []
    i = 2
    while i < num:
        if isPrimeNumber(i) and i == Reverse(i):
            arr.append(i)
        i += 1
    return arr

print RPrimeNumber(1000)

6) 平方回文素数 ->中

1.问题描述:
素数的平方是回文,比如11 * 11=121。

求不超过1000的平方回文素数。

2.参考源码:

#!/usr/bin/env python

import math
def isPrimeNumber(num):
    i = 2
    x = math.sqrt(num)
    while i < x:
        if num%i == 0:
            return False
        i += 1
    return True

def Reverse(num):
    rNum = 0
    while num:
        rNum = rNum*10 + num%10
        num /= 10
    return rNum

def RPrimeNumber(num):
    arr = []
    i = 2
    while i < num:
        if isPrimeNumber(i) and i**2 == Reverse(i**2):
            arr.append(i)
        i += 1
    return arr

print RPrimeNumber(1000)

7) 梅森尼数 ->中

1.问题描述:
法国数学家梅森尼对这类形如2 ^ n-1的素数特别感兴趣,做过很多有意义的工作,后人把此类数命名为梅森尼数。
已经证明了,如果2 ^ n-1是素数,则幂指数n必须是素数,然而,反过来并不对,当n是素数时,2 ^ n-1不一定是素数。例如,人们已经找出2 ^ 11-1是一个合数,23可以除尽它,2 ^ 23-1是一个合数,47可以除尽它。

编程找出指数n在(2,50)中的梅森尼数。

2.参考源码:

#!/usr/bin/env python

import math
def isPrimeNumber(num):
    i = 2
    x = math.sqrt(num)
    while i < x:
        if num%i == 0:
            return False
        i += 1
    return True

def masonNumber(num):
    arr = []
    for i in xrange(2, num + 1):
        if isPrimeNumber(i) and isPrimeNumber(2**i - 1):
            arr.append(2**i - 1)
    return arr

print masonNumber(50)

8) 哥德巴赫猜想 ->中

1.问题描述:
众所周知,哥德巴赫猜想的证明是一个世界性的数学难题,至今未能完全解决。我国著名数学家陈景润为哥德巴赫猜想的证明作出过杰出的贡献。
所谓哥德巴赫猜想是说任何一个大于2的偶数都能表示成为两个素数之和。

编写程序,验证指定范围内哥德巴赫猜想的正确性,也就是近似证明哥德巴赫猜想。

2.参考源码:

#!/usr/bin/env python

def isPrimeNumber(n, s):
    for k in s: 
        if k ** 2 > n: break
        if n % k == 0: return False
    return True

def fun():
    s = [3]
    for n in xrange(6, 100000, 2):
        f = False
        for k in s:  
            t = n - k
            if t < k:
                break
            if isPrimeNumber(t, s):
                #print ‘%s = %s + %s‘ % (n, k, t)
                if t > s[-1]: s.append(t)
                f = True
                break
        if not f: raise Exception

fun()

9) 等差素数数列 ->中

1.问题描述:
类似7、37、67、97、107、137、167、197,这样由素数组成的数列叫做等差素数数列。素数数列具有项数的限制,一般指素数数列的项数有多少个连续项,最多可以存在多少个连续项。

编程找出100以内的等差素数数列。

2.参考源码:

#coding:utf-8

# 解题步骤:
#    1. 筛法找到100所有素数
#    2. 对于素数list内素有俩两组合,构造等差数列a0, a1项
#    3. 计算出a2, 查表判断a2是否是素数,是素数则能构成素数等差序列, 计算a3...

def findAllPrime(n):
    pt = [True] * n
    prime = []

    for p in range(2, n):
        if not pt[p]: continue
        prime.append(p)
        for i in range(p * p, n, p):
            pt[i] = False

    return prime, pt

prime, pt = findAllPrime(100)
print prime

for i in range(len(prime)):
    for j in range(i + 1, len(prime)):
        a0, a1 = prime[i], prime[j]
        an = a1 + a1 - a0
        s = []
        while an < 100 and pt[an]:
            s.append(an)
            an += a1 - a0
        if s:
            print [a0, a1] + s

趣味图形

1) 回型矩阵 ->中

1.问题描述:
打印回型矩阵如图:
1 2 3 4 5 6 7 8
28 29 30 31 32 33 34 9
27 48 49 50 51 52 35 10
26 47 60 61 62 53 36 11
25 46 59 64 63 54 37 12
24 45 58 57 56 55 38 13
23 44 43 42 41 40 39 14
22 21 20 19 18 17 16 15

2.参考源码:

#!/usr/bin/env python

def snakeNum(n):
    a = [[0 for i in range(n)] for j in range(n)]

    p = 0
    q = n - 1
    t = 1
    while p < q:
        for i in xrange(p, q):
            a[p][i] = t
            t += 1
        for i in xrange(p, q):
            a[i][q] = t
            t += 1
        for i in xrange(q, p, -1):
            a[q][i] = t
            t += 1
        for i in xrange(q, p, -1):
            a[i][p] = t
            t += 1
        p += 1
        q -= 1
    if p == q: a[p][p] = t
    for i in range(n):
        print a[i]

snakeNum(8)

2) 九九乘法表 ->易

1.问题描述:

打印乘法表如图:
1*1=1
2*1=2   2*2=4
3*1=3   3*2=6      3*3=9
4*1=4   4*2=8      4*3=12    4*4=16
5*1=5   5*2=10    5*3=15    5*4=20     5*5=25
6*1=6   6*2=12    6*3=18    6*4=24     6*5=30    6*6=36
7*1=7   7*2=14    7*3=21    7*4=28     7*5=35    7*6=42    7*7=49
8*1=8   8*2=16    8*3=24    8*4=32     8*5=40    8*6=48    8*7=56    8*8=64
9*1=9   9*2=18    9*3=27    9*4=36     9*5=45    9*6=54    9*7=63    9*8=72    9*9=81

2.参考源码:

 def fun():
     for line in xrange(1,10):
         for row in xrange(1,line + 1):
           s=str(line) + ‘ * ‘ + str(row) + ‘ = ‘ + str(line * row)
         print s.ljust(12),‘|‘,
     print ‘‘

 fun()

3) 杨辉三角 ->易

1.问题描述:

根据输入行数,打印出杨辉三角,如图所示。
1
1    1
1    2    1
1    3    3     1
1    4    6     4   1
1    5    10   10   5   1
1    6    15   20   15  6   1

2.参考源码:

#!/user/bin/python

def yang(floor):
    now = []
    for x in xrange(floor):
        now.append(1)
        for index in xrange(len(now) - 2,0,-1):
            now[index] = now[index - 1] + now[index]
        print now

yang(5)

数学问题

1) 天平秤物 ->难

1.问题描述:
有4个砝码,总重量是40克,砝码的质量是整数,且各不相等。请确定它们的质量,使之能称出1 ~ 40克任何整数质量的物体。

2.参考源码:

def fun(m, n):
    a = []
    while n > 1:
        k = 2 * sum(a) + 1
        a.append(k)
        n -= 1

    k = m - sum(a)
    if k - 2 * sum(a) < 2:
        a.append(k)
        return a

    return None

print fun(40, 4)

2) 黑色星期五 ->易

1.问题描述:
黑色星期五源于西方的宗教信仰与迷信:耶稣基督死在星期五,而13是不吉利的数字。两者的结合令人相信当天会发生不幸的事情。星期五和数字13都代表着坏运气,两个不幸的个体最后结合成超级不幸的一天。所以,不管哪个月的13日又恰逢星期五就叫“黑色星期五”。找出未来几年哪些天是“黑色星期五”。

2.参考源码:

#!/usr/bin/env python

3) 存钱问题 ->中

1.问题描述:
父亲准备为小龙的四年大学生活一次性储蓄一笔钱,使用整存零取的方式,控制小龙每月月初取1000元准备这个月使用。假设银行整存零取的年利息1.71%,请算出父亲至少需要存入多少钱才行。

2.参考源码:

a = 1000

for i in xrange(47,0,-1):
    a /= (0.0171 / 12) + 1
    a += 1000

a = round(a,2)
print a

4) 赛场统分 ->中

1.问题描述:
在编程竞赛中,有10个评委为参赛的选手打分,分数为0 ~ 100分。选手最后得分为:去掉一个最高分和一个最低分后其余8个分数的平均值。

请编写一个程序实现。

2.参考源码:

import random

score = [random.randint(1,100) for x in xrange(10)]

print scoure

score.remove(max(scoure))
score.remove(min(scoure))

result = sum(score) / len(score)

print result

5) 肇事车辆 ->中

1.问题描述:
有一个卡车司机肇事后想逃跑,但是被三个人看见了其车牌号,但是都没看全,甲说:车牌的前两位是一样的;乙说:车牌的后两位一样的,但与前两位不一样;丙说:车牌是一个数字的平方。

请编写一个程序计算该车牌号是多少(车牌号4位数)。

2.参考源码:

import math
def FindHim():
    for x in xrange(10):
        for y in xrange(10):
        if x != y:
        result = x * 1100 + y * 11
        test = math.sqrt(result) 
        if test.is_integer():
            return result

print FindHim()

6) 分糖果 ->中

1.问题描述:
10个小孩围城一圈分糖果,老师分给第1个小孩10块,第2个小孩2块,第3个小孩8块,第4个小孩22块,第5个小孩16块,第6个小孩4块,第7个小孩10块,第8个小孩6块,第9个小孩14块,第10个小孩20块。然后所有的小孩同时将手中的糖分一半给右边的小孩;糖块数为奇数的人可向老师要一块。

问经过这样几次后大家手中的糖的块数一样多? 每人各有多少块糖?

2.参考源码:

#coding:utf-8

#解题思路:
#    1.用列表存储当前小朋友的糖果数.
#    2.模拟糖果传递过程, (s[i-1] + s[i]) / 2
#    3.判断是否全相等

def fun():
    s = [10, 2, 8, 22, 16, 4, 10, 6, 14, 20]

    count = 0
    while not all([x == s[0] for x in s]):
        s = [(s[i-1] + s[i]) / 2 for i in range(10)]
        s = [x + x % 2 for x in s]
        count += 1

    print count, s

fun()

7) 平分七框鱼 ->中

1.问题描述:
甲、乙、丙三位渔夫出海打鱼,他们随船带了21只箩筐。当晚返航时,他们发现有7筐装满了鱼,还有7筐只装了半筐鱼,另外7筐则是空的。由于他们没有秤,只好通过目测认为7个满筐鱼的重量是相等的,7个半筐鱼的重量也是相等的。

在不将鱼倒出来的前提下,怎么将鱼和筐平分三份?

2.参考源码:

#coding:utf-8

#解题思路:
#    1.我们可以计算得知,每人应得3.5框鱼
#    2.穷举每人拿到整框数,a, b, c
#    3.计算每人应拿半框数,ah, bh, ch, 
#    4.ah + bh + ch == 7 ?

for a in range(4):
    for b in range(min(4, 7 - a + 1, a + 1)):
        c = 7 - a - b
        if c >= 4 or c > b:
            continue
        h = map(lambda x: int((3.5 - x) / 0.5), (a, b, c))
        if sum(h) == 7:
            print ‘-‘ * 20
            for x, y in zip((a, b, c), h):
                print x, y, 7 - x - y

趣味方程

1) 百鸡百钱 ->中

1.问题描述:
我国古代数学家张丘建在《张丘建算经》一书中提出了“百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?这个问题的大致意思是这样的:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱。

如果用100文钱买100只鸡,那么公鸡、母鸡和小鸡各应该买多少只呢?

2.参考源码:

#!/usr/bin/env python
#coding:utf-8
def fun():
    for i in xrange(0, 100, 3):
        for j in xrange(100):
            if 100 - i - j >= 0 and 5*(100 - i - j) + i/3 + j == 100 and (i/3 + j)%5 == 0:
                print ‘小鸡%d只,母鸡%d只,公鸡%d只‘%(i, j, 100 - i - j)

fun()

2) 楼梯台阶 ->中

1.问题描述:
一个共有10个台阶的楼梯,从下面走到上面,一次只能迈一个台阶或两个台阶,并且不能后退,走完这个楼梯共有多少种方法。

2.参考源码:

#coding:utf-8

def fun(n):
    res = fun.cache.get(n, None)
    if res:
        return res

    res = []
    for step in (1, 2):
        if n < step: break
        for p in fun(n - step):
            res.append([step] + p)

    fun.cache[n] = res
    return res
fun.cache = {0:[[]]}

3) 换硬币 ->中

1.问题描述:
设有n种不同面值的硬币,各硬币的面值存于数组w[i]中。现要用这些面值的硬币来找钱,可以使用的各种面值的硬币个数存于数组S[i]中。

对任意钱数0≤m,设计一个用最少硬币找钱m的方法。

2.参考源码:

def  fun(value,money):

    times = value / money[0]

    if len(money) == 1:
        if value % money[0] == 0:
            return times,[times]
        else:
            return None

    result = (value + 1,0)
    for i in xrange(times + 1):

        residue = value - money[0] * i
        get = fun(residue,money[1:])

       if get != None and get[0] + i< result[0]:
           result = (get[0] + i,[i] + get[1])

    if result[1] == 0:
        return None
    else:
        return result

4) 求s=a+aa+aaa+aa…a的值 ->中

1.问题描述:
求表达式s=a+aa+aaa+aa…a的值,要求a从键盘接收,表达式的长度也从键盘接受。

2.参考源码:

#!/usr/bin/python

def fun(a, n):
   s = 0
   for i in xrange(1, 2*n, 2):
      s = s*10 + i*a
   return s

a = input()
n = input()
print fun(a, n)

5) 鸡兔同笼 ->中

1.问题描述:
鸡兔同笼问题最早记载于1500年前的《孙子算经》,这是我国古代一个非常有名的问题。鸡兔同笼的原文如下:
今有鸡兔同笼,上有三十五头,下有九十四足,问鸡兔各几何?
这个问

以上是关于Python 趣味百题的主要内容,如果未能解决你的问题,请参考以下文章

python-趣味百题4

python-趣味百题3

4.13趣味百题第七题

4.18趣味百题12题

LeetCode第一百题—相同的数—Python实现

python百题大冲关