趣味算法之趣味分数

# -*- coding: utf-8 -*-
"""
Created on Wed Dec 07 18:43:25 2016
趣味百题之趣味分数

@author: onlyyo
"""

# 1.求任意两个整数的最大公约数
def fun(n,m):
    
    if n > m:
        n,m = m,n
    while True:
        m,n = n, m%n
        if n == 0:
            break
        
    return m
    
fun(17,5)

#2.求任意3个整数的最小公倍数。
def fun(a,b,c):
    if b > a:
        a,b = b,a
    if c > a:
        a,c = c,a
        
    ans = a
    while ans%b or ans%c:
        ans += a
        
    return ans    
    
fun(4,6,8) 

# 3. 比较任意两个分数大小
def fun(x,y):
    a,b = x
    c,d = y
    
    diff = a*d - b*c
    if diff > 0:
        print "{0}/{1} 比 {2}/{3}大".format(a,b,c,d)
    else:
        print "{0}/{1} 比 {2}/{3}小".format(a,b,c,d)
    
fun((2,5),(3,6))    
    
  
# 4.求这样的4个自然数p、q、r、s(p<=q<=r<=s),使得一下等式成立:1/p+1/q+1/r+1/s=1。
def fun():
    a = 2
    # 刻画循环条件:
    # 1) 4/a > 1/a + 1/b + 1/c + 1/d = 1 (因a<b<c<d), 因此 a < 4
    while a < 4:
        b = a + 1
        # 刻画循环条件:
        # 1) 1/a + 1/b < 1, 1/a + 1/b最大为 1/2+1/3, 此条件恒成立
        # 2) 1/a + 3/b > 1/a + 1/b + 1/c + 1/d = 1 (因a<b<c<d), 通分得 b + 3a > ab
        while b+3*a > a*b:
            c = b + 1
            # 刻画循环条件:
            # 1) 1/a + 1/b + 1/c < 1, 通分得 bc + ac + ab < abc
            # 2) 1/a + 1/b + 2/c > 1/a + 1/b + 1/c + 1/d = 1 (因a<b<c<d), 通分得 bc + ac + 2ab > 1
            while b*c+a*c+a*b<a*b*c and b*c+a*c+2*a*b > a*b*c:
                d = c + 1
                # 刻画循环条件:
                # 1) 1/a + 1/b + 1/c + 1/d > 1
                while True:
                    k = b*c*d+a*c*d+a*b*d+a*b*c 
                    if k == a*b*c*d: print 'find:', a, b, c, d
                    if k <= a*b*c*d: break
                    d += 1
                c += 1
            b += 1
        a += 1
fun()


'''# 5.分子是1的分数,叫单位分数。古代埃及人在进行分数运算时,只使用分子是1的分数,
因此这种分数也叫做埃及分数式,或者叫单分子分数。要求随便输入一个真分数,将该分数
分解为埃及分数式,如3/7=1/3+1/11+1/231.'''

#解题思路:
#   1. 对于一个真分数b分之a, 找最接近的1/k
#   2. 如果a % b == 0, 找到k = b/a
#   3. 如果a % b != 0, 找到k = b/a + 1

def fun(a, b):
    k = b / a
    if b % a == 0:
        res = '1/%s' % k
    else:
        k += 1
        res = '1/%s + %s' % (k, fun(a * k - b, b * k))
    return res

print fun(4, 7)

# 6.有一分数序列:2/1,3/2 ,5/3, 8/5,13/8 ,21/13,...,求出这个数列的前20项之和。

def fun(n):
    a = 2
    b = 3
    Sum = 2
    while n>2:
        a,b = b,a+b
        Sum += float(b/a)
        n = n - 1
    return Sum    


# 7.猴子分桃
'''
1979年,李政道博士给中国科技大学少年班出过一道知趣题:5只猴子分一堆桃子,
怎么也分不成5等分,只好先去睡觉,准备第二天分。夜里1只猴子偷偷爬起来,先吃掉一个桃子,
然后将其分为5等份,藏起自己的一份就去睡觉了;第二只猴子又爬起来,吃掉一个桃子后,也将
桃子分成5等份,藏起自己的一份睡觉去了;以后的3只猴子都先后照此办理。问最初有多少个桃子?'''

def show(n):
    for i in xrange(1,6):
        t = (n - 1) / 5
        print '%d. 总数%d个, 第%i只猴吃一个, 拿走%s个。' % (i, n, i, t)
        n = 4 * t

def fun():
    k = 1
    while True:
        t = k
        #当前猴子拿走tc,吃拿之前总量应为 5 * tc + 1
        #前个猴子拿走tp,则有 4 * tp = 5 * tc + 1  
        for i in xrange(4):
            t = 5 * t + 1
            if t % 4: break
            t /= 4
        else:
             print 5 * t + 1
             show(5 * t + 1)
             # 我们只找最小整数解
             break
        k += 1

fun()

    


  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值