一人一python挑战题解

 

题目id: 1 just print a+b

give you two var a and b, print the value of a+b, just do it!!

print a+b

题目id:  2 list排序

给你一个list L, 如 L=[2,8,3,50], 对L进行升序排序并输出

print sorted(L)

题目id: 3  字符串逆序

给你一个字符串 a, 如a=‘12345’,对a进行逆序输出a。

print a[::-1]

题目id:4   输出字典key

给你一字典a,如a={1:1,2:2,3:3},输出字典a的key,以','链接,如‘1,2,3'。

print ','.join(a.keys())

 

题目id:  5  输出字符奇数位置的字符串

给你一个字符串 a, 输出字符奇数位置的字符串。如a=‘12345’,则输出135。

str1=''
for i in range(len(a)):
    if i%2==0:
        str1 += str(a[i])
print str1

 

题目id:6  求解100以内的所有素数

输出100以内的所有素数,素数之间以一个空格区分

import math
def isPrime(n):
    if n<=1:
        return False
    for i in range(2,int(math.sqrt(n))+1):
        if n%i == 0:
            return False
    return True
list = []
for i in range(1,100):
    if isPrime(i):
        list.append(str(i))
print ' '.join(list)

 题目id:7  求矩形面积

已知矩形长a,宽b,输出其面积和周长,面积和周长以一个空格隔开

print "%d %d"%(a*b,2*(a+b))

 题目id:8  求中位数

给你一个list L, 如 L=[0,1,2,3,4], 输出L的中位数(若结果为小数,则保留一位小数)。

n = len(L) 
L.sort()     //注意sorted()函数和sort()函数的区别,sorted()不影响L的结构,而sort()影响L的结构
print (L[n/2] if n&1 else round(float(L[n/2-1]+L[n/2])/2,1))

题目id:9  最大公约数

给你两个正整数a和b, 输出它们的最大公约数。

def gcd(a,b):
    if a < b:
        a,b = b,a
    while b:
        a,b=b,a%b
    return a
print gcd(a,b)

题目id:10  最小公倍数

给你两个正整数a和b, 输出它们的最小公倍数

def gcd(a,b):
    if a < b:
        a,b = b,a
    while b:
        a,b=b,a%b
    return a
print a*b/gcd(a,b)

题目id:11  结尾0的个数

给你一个正整数列表 L, 如 L=[2,8,3,50], 输出L内所有数字的乘积末尾0的个数,

def getFactorNum(num,factor):
    cnt = 0
    while num%factor == 0:
        cnt+=1
        num /=factor
    return cnt
fiveNum = 0
twoNum = 0
for num in L:
    fiveNum += getFactorNum(num,5)
    twoNum += getFactorNum(num,2)
print min(fiveNum,twoNum)

题目id:12  结尾非零数的奇偶性

给你一个正整数列表 L, 如 L=[2,8,3,50], 判断列表内所有数字乘积的最后一个非零数字的奇偶性,

def getFactorNum(num,factor):
    cnt = 0
    while num%factor == 0:
        cnt+=1
        num /=factor
    return cnt
fiveNum = 0
twoNum = 0
for num in L:
    fiveNum += getFactorNum(num,5)
    twoNum += getFactorNum(num,2)
print ( 1 if fiveNum >= twoNum else 0)

题目id:13  光棍的悲伤

给你一个整数a,数出a在二进制表示下1的个数,并输出。

cnt = 0
while a:
    cnt += a&1
    a >>= 1
print cnt

题目id:14  Python之美

输出Python之禅
注意:输出python之禅的源码即可,不用转换为英文。

import this
print this.s

题目id:15  大小写转换

给定一个字符串a, 将a中的大写字母 转换成小写,其它字符不变,并输出。

print a.lower()

题目id:16 人民币金额打印

银行在打印票据的时候,常常需要将阿拉伯数字表示的人民币金额转换为大写表示,现在请你来完成这样一个程序。
在中文大写方式中,0到10以及100、1000、10000被依次表示为:
零壹贰叁肆伍陆柒捌玖拾佰仟万
以下的例子示范了阿拉伯数字到人民币大写的转换规则:

1 壹圆
11 壹拾壹圆
111 壹佰壹拾壹圆
101 壹佰零壹圆
-1000 负壹仟圆
1234567 壹佰贰拾叁万肆仟伍佰陆拾柒圆

现在给你一个整数a(|a|<100000000), 打印出人民币大写表示

d={0:'',1:'',2:'',3:'',4:'',5:'',6:'',7:'',8:'',9:''}
unit = {0:'',1:'',2:'',3:'',4:''}
b = abs(a)
def transferMoney(b,s,outOfRange):
    s.append('') if outOfRange else s.append('')
    cnt = 0
    flag = False
    if b == 0: 
        s.append(d[0])
    else:
        while b:
            if b%10:
                flag = True
                s.append(unit[cnt])
            if flag:
                s.append(d[b%10])
            b/=10
            cnt+=1
s=[]
transferMoney(b%10000,s,False)
if b >= 10000:
    transferMoney(b/10000,s,True)

if a < 0:
    s.append('')
print "".join(s[::-1])

题目id:17 公约数的个数

 给你两个正整数a,b,  输出它们公约数的个数。

def gcd(a,b):
    if a < b:
        a,b = b,a
    while b:
        a,b = b,a%b
    return a
cnt = 1
for i in range(1,gcd(a,b)):
    if a%i == 0 and b%i ==0:
        cnt +=1
print cnt

题目id:18    逆解最大公约数与最小公倍数

我们经常遇到的问题是给你两个数,要你求最大公约数和最小公倍数。
今天我们反其道而行之,给你两个数a和b,计算出它们分别是哪两个数的最大公约数和最小公倍数。
输出这两个数,小的在前,大的在后,以空格隔开。若有多组解,输出它们之和最小的那组。

import sys
def gcd(a,b):
    if a < b:
        a,b = b,a
    while b:
        a,b = b,a%b
    return a

c= b/a+1
minv,mina,minb= sys.maxint,0,0
for i in range(1,c):
    for j in range(i,c):
        if gcd(i,j) == 1 and a*i*j == b:
            if minv > (a*i+a*j):
                minv,mina,minb = (a*i+a*j),a*i,a*j
print '%d %d'%(mina,minb)

题目id:19  单身情歌

抓不住爱情的我
总是眼睁睁看它溜走
...

现在来练习一下发现爱的能力,给你一个字符串a,如果其中包含"LOVE"(love不区分大小写)则输出LOVE,否则输出SINGLE。

print ("LOVE" if "love" in a.lower() else "SINGLE" )

题目id:20 信息加密

给你个小写英文字符串a和一个非负数b(0<=b<26), 将a中的每个小写字符替换成字母表中比它大b的字母。
这里将字母表的z和a相连,如果超过了z就回到了a。例如a="cagy",b=3, 则输出 fdjb

c=[]
for letter in a:
    if letter.islower():
        c.append(chr((ord(letter)+b-97)%26+97))
    else:
        c.append(letter)
print "".join(c)

题目id:21  回文子串

给你一个字符串a和一个正整数n,判断a中是否存在长度为n的回文子串。如果存在,则输出YES,否则输出NO。
回文串的定义:记串str逆序之后的字符串是str1,若str=str1,则称str是回文串,如"abcba".

def is_palindrome(a):
    return (True if a == a[::-1] else False)

for index in range(len(a)-n+1):
    if is_palindrome(a[index:index+n]):
        print 'YES'
        break
else:
    print 'NO'

题目id:22  时间就是金钱

给你两个时间st和et(00:00:00<=st <= et<=23:59:59), 请你给出这两个时间间隔的秒数。
如:st="00:00:00", et="00:00:10", 则输出10.

stTime = st.split(':')
etTime = et.split(':')
hour,minute,second = int(etTime[0])-int(stTime[0]),int(etTime[1])-int(stTime[1]),int(etTime[2])-int(stTime[2])
print hour*3600+minute*60+second

题目id:23  365 Or 366?

一年有多少天,这是个大问题,很值得思考。现在给你一个年份year(year为四位数字的字符串,如"2008","0012"),
你输出这一年的天数。如year="2013", 则输出365。

def isLeapYear(year):
    return (year%4 == 0 and year%100 )or year%400 == 0
print (366 if isLeapYear(int(year)) else 365)

题目id:24  一马当先

下过象棋的人都知道,马只能走'日'字形(包括旋转90°的日),现在想象一下,给你一个n行m列网格棋盘,
棋盘的左下角有一匹马,请你计算至少需要几步可以将它移动到棋盘的右上角,若无法走到,则输出-1.
如n=1,m=2,则至少需要1步;若n=1,m=3,则输出-1

主要用深度优先搜索算法去做

n +=1
m +=1
visit = [([False]*n) for i in range(m)]
step  = ((2,1),(1,2),(-1,2),(-2,1),(-2,-1),(-1,-2),(1,-2),(2,-1))
flag  = False
cnt = 0 
minCnt = n*m
def dfs(row,col):
    global minCnt
    global cnt
    global flag
    global step
    global visit
    if row == m-1 and col == n-1:
        flag = True
        if minCnt > cnt:
            minCnt = cnt
        return
    for item in step:
        newRow,newCol= row+item[0],col+item[1]
        if newRow>=0 and newRow<m and newCol>=0 and newCol < n:
            if visit[newRow][newCol] == False:
                visit[newRow][newCol] =True
                cnt +=1
                dfs(newRow,newCol)
                cnt -=1
                visit[newRow][newCol] =False
visit[0][0] =True
dfs(0,0)           
print (minCnt if flag else -1)

题目id:25  格式化时间

给你一个时间t(t是一个字典,共有六个字符串key(year,month,day,hour,minute,second),值为每个值为数字组成的字符串,
如t={'year':'2013','month':'9','day':'30','hour':'16','minute':'45','second':'2'}
请将其按照以下格式输出, 格式:XXXX-XX-XX XX:XX:XX。如上例应该输出: 2013-09-30 16:45:02。

d =[t['year'].zfill(4),t['month'].zfill(2),t['day'].zfill(2),t['hour'].zfill(2),t['minute'].zfill(2),t['second'].zfill(2)]
print '-'.join(d[:3]),':'.join(d[3:])

题目id:26  序列判断

给你一个整数组成的列表L,按照下列条件输出:
若L是升序排列的,则输出"UP";
若L是降序排列的,则输出"DOWN";
若L无序,则输出"WRONG"。

if L == sorted(L):
    print 'UP'
elif L == sorted(L,reverse=True):
    print 'DOWN'
else:
    print 'WRONG'

题目id:27  加油站

每个加油站加油都有一个上限,保存在列表limit中,即limit[i]为第i个加油站加油的上限,
而从第i个加油站开车开到第(i+1)%n个加油站需要cost[i]升油,cost为一个列表。
现在有一辆开始时没有油的车,要从一个加油站出发绕这个公路跑一圈回到起点。
给你整数n,列表limit和列表cost,你来判断能否完成任务。
如果能够完成任务,输出起始的加油站编号,如果有多个,输出编号最小的。
如果不能完成任务,输出-1。

for i in range(n):
    sumLimit,sumCost = 0,0
    for k in range(n):
        sumLimit +=limit[(k+i)%n]
        sumCost += cost[(k+i)%n]
        if sumCost > sumLimit:
            break
    else:
        print i
        break
else:
    print -1

题目id:28  相同数字

给你一个整数列表L,判断L中是否存在相同的数字,
若存在,输出YES,否则输出NO。

print ('NO' if len(set(L)) == len(L) else 'YES')

题目id:29  判断三角形

给你三个整数a,b,c, 判断能否以它们为三个边长构成三角形。
若能,输出YES,否则输出NO。

d=[a,b,c]
d.sort()
if d[0]+d[1]>d[2] and abs(d[0]-d[1])<d[2]:
    print 'YES'
else:
    print 'NO'

题目id:30  National Day

马上国庆节了,用一个英文单词描述你此时此刻的心情。

print 'Happy'

题目id:31  山峰的个数

十一假期,小P出去爬山,爬山的过程中每隔10米他都会记录当前点的海拔高度(以一个浮点数表示),
这些值序列保存在一个由浮点数组成的列表h中。回到家中,小P想研究一下自己经过了几个山峰,请你帮他计算一下,输出结果。
例如:h=[0.9,1.2,1.22,1.1,1.6,0.99], 将这些高度顺序连线,会发现有两个山峰,故输出一个2(序列两端不算山峰)

cnt = 0
for i in xrange(1,len(h)-1):
    if h[i]>h[i-1] and h[i]>h[i+1]:
        cnt += 1
print cnt

题目id:32  三角形形状

给以一个三角形的三边长a,b和c(边长是浮点数),请你判断三角形的形状。
若是锐角三角形,输出R,
若是直角三角形,输出Z,
若是钝角三角形,输出D,
若三边长不能构成三角形,输出W.

d=[a,b,c]
d.sort()
if d[0]+d[1] > d[2] and abs(d[0]-d[1]) < d[2]:
    if d[0]**2+d[1]**2 == d[2]**2:
        print 'Z'
    elif d[0]**2+d[1]**2 >d[2]**2:
        print 'R'
    else:
        print 'D'
else:
    print 'W'

题目id:33  大幂次运算

给你两个正整数a(0 < a < 100000)和n(0 <= n <=100000000000),计算(a^n) % 20132013并输出结果

print pow(a,n,20132013)

题目id:34  密码生成

生活在当代社会,我们要记住很多密码,银行卡,qq,人人,微博,邮箱等等。小P经过一番思索之后,发明了下面这种生成密码方法:
给定两个正整数a和b, 利用a / b我们会到的一个长度无限的小数(若a / b不是无限小数,
比如1/2=0.5,我们认为0.5是0.5000000...,同样将其看做无限长的小数),小P将该小数点后第x位到第y位的数字
当做密码,这样,无论密码有多长,小P只要记住a,b,x,y四个数字就可以了,牢记密码再也不是那么困难的事情了。
现在告诉你a,b,x,y(0 < a,b <= 20132013, 0 < x <= y < 100000000000),请你输出密码。
例如:a = 1, b = 2, x = 1, y = 4, 则 a / b = 0.5000000..., 输出小数点后第1到4位数字,即5000

decimals = []
if a > b :
a =a%b
cnt = 0
flag = False
x-=1
y-=1
while cnt <= y:
    decimalPart,a = divmod(a*10**1024,b)
    if flag:
        decimals.append(str(decimalPart).zfill(1024))
    if x >= cnt and x < cnt+1024:
        flag = True
        decimals.append((str(decimalPart).zfill(1024))[x-cnt:])
    if y>=cnt and y< cnt+1024:
        break
    cnt +=1024
if y/1024 !=x/1024:
    decimals[-1]=(str(decimals[-1]))[:y-cnt+1]
else:
    decimals[-1]=(str(decimals[-1]))[:y-x+1]
print ''.join(decimals)

题目id:35  最大连续子序列

给你一个整数list L, 如 L=[2,-3,3,50], 求L的一个连续子序列,使其和最大,输出最大子序列的和。
例如,对于L=[2,-3,3,50], 输出53(分析:很明显,该列表最大连续子序列为[3,50]).

def maxSubSum(L):
    maxSum,thisSum= 0,0
    for item in L:
        thisSum += item;
        if thisSum > maxSum:
            maxSum = thisSum
        elif thisSum < 0:
            thisSum = 0
    return maxSum

print maxSubSum(L)

题目id:36  最大非连续子序列

给你一个整数list L, 如 L=[2,-3,3,50], 求L的一个非连续子序列,使其和最大,输出最大子序列的和。
这里非连续子序列的定义是,子序列中任意相邻的两个数在原序列里都不相邻。
例如,对于L=[2,-3,3,50], 输出52(分析:很明显,该列表最大非连续子序列为[2,50]).

注意类似这种情况L=[-1,-1,-1,-1,-1,0]

if len(L) >= 2:
    dp=[L[0],max(L[0],L[1])]
    for i in range(2,len(L)):
        dp.append(max(dp[i-1],max(L[i]+dp[i-2],L[i])))
    print dp[len(L)-1]
else:
    print L[0]

题目id:37  简单题之勾股定理

 给你直角三角形的两个直角边的边长a,b,请你求出其斜边边长,结果保留小数点后三位小数。

如a=3, b =4, 则输出5.000。

import math
print "%.3f"%math.sqrt(a**2+b**2)

题目id:38  简单题之列表转换

给你一个字符串列表L,请用一行代码将列表所有元素拼接成一个字符串并输出。
如L=['abc','d','efg'], 则输出abcdefg。

print ''.join(L)

题目id:39  简单题之输出格式练习

 给你一个字符串列表L,用一行代码顺序输出L中的元素,元素之间以一个空格隔开,注意行尾不要有空格,输出单独占一行。

如L=['abc','d','efg'], 则输出abc d efg。

print ' '.join(L)

 题目id:40  整数解

 给你两个整数a和b(-10000<a,b<10000),请你判断是否存在两个整数,他们的和为a,乘积为b。

若存在,输出Yes,否则输出No
例如:a=9,b=15, 此时不存在两个整数满足上述条件,所以应该输出No。

import math
x1 = int(float(a+math.sqrt(a**2-4*b))/2)
x2 = int(float(a-math.sqrt(a**2-4*b))/2)
if x1+x2 == a and x1*x2 == b:
    print 'Yes'
else:
    print 'No'

题目id:41  Py数

 Py从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,

这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,
同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。
Py非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Py数。
现在给你一个十进制4位数n,你来判断n是不是Py数,若是,则输出Yes,否则输出No。
如n=2992,则输出Yes; n = 9999,则输出No。

def getSumByValue(n,value):
    res = 0
    while n:
        res += n%value
        n /=value
    return res

if getSumByValue(n,10) == getSumByValue(n,16) == getSumByValue(n,12):
    print 'Yes'
else:
    print 'No'

题目id:42  分拆素数和

把一个偶数拆成两个不同素数的和,有几种拆法呢?
现在来考虑考虑这个问题,给你一个不超过10000的正的偶数n,
计算将该数拆成两个不同的素数之和的方法数,并输出。
如n=10,可以拆成3+7,只有这一种方法,因此输出1.

import math
def is_prime(num):
    for i in range(2,int(math.sqrt(num)+1)):
        if num%i == 0:
            return False
    return True

cnt = 0
for i in range(2,n/2):                           #注意1不是素数
    if is_prime(i) and is_prime(n-i):
        cnt +=1
print cnt

题目id:43  斐波那契数列

斐波那契数列为1,1,2,3,5,8...。数列从第三项起满足,该项的数是其前面两个数之和。
现在给你一个正整数n(n < 10000), 请你求出第n个斐波那契数取模20132013的值(斐波那契数列的编号从1开始)。

a,b=1,1
for i in range(3,n+1):
    a,b=b%20132013,(a+b)%20132013
print b

题目id:44  超级楼梯

有一楼梯共n级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第n级,共有多少种走法?
现在给你一个正整数n(0<n<40),请你输出不同的走法数。
如n=2,则输出1(你只有一种走法,走一步,从第一级到第二级)

a,b=1,1
for i in range(3,n+1):
    a,b=b,(a+b)
print b

题目id:45  砝码问题

有一组砝码,重量互不相等,分别为m1、m2、m3……mn;它们可取的最大数量分别为x1、x2、x3……xn。
现要用这些砝码去称物体的重量,问能称出多少种不同的重量。
现在给你两个正整数列表w和n, 列表w中的第i个元素w[i]表示第i个砝码的重量,列表n的第
i个元素n[i]表示砝码i的最大数量。i从0开始,请你输出不同重量的种数。
如:w=[1,2], n=[2,1], 则输出5(分析:共有五种重量:0,1,2,3,4)

母函数的问题

m = set()
for i in range(n[0]+1):
    m.add(w[0]*i)
for i in range(1,len(n)):
    tmp = m.copy()
    m.clear()
    for j in range(n[i]+1):
        for k in tmp:
            m.add(w[i]*j+k)
print len(m)

题目id:45  测试贡献题目

给你一个list L, 如 L=[2,8,3,50], 对L进行降序排序并输出, 如样例L的结果为[50,8,3,2]

print sorted(L,reverse = True)

题目id:46  取石子游戏

有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,
一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。
现在给出初始的两堆石子的数目a和b,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。
如果你是胜者,输出Win,否则输出Loose。
例如,a=3,b=1, 则输出Win(你先在a中取一个,此时a=2,b=1,此时无论对方怎么取,你都能将所有石子都拿走).

博弈论问题
import math
p = (math.sqrt(float(5))+1)/float(2)
c = abs(a-b)
if a > b:
    a = b
if a == int(p*c):
    print "Loose"
else: print "Win"

题目id:47  杨辉三角

还记得中学时候学过的杨辉三角吗?具体的定义这里不再描述,你可以参考以下的图形:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
..............
先在给你一个正整数n,请你输出杨辉三角的前n层
注意:层数从1开始计数,每层数字之间用一个空格隔开,行尾不要有空格。
如n=2,则输出:
1
1 1
trangle = [['1'],['1','1']]

def print_trangle(n):
    for i in range(n):
        print ' '.join(trangle[i])   
for i in range(3,n+1):
    tmp=['1']
    newRow= trangle[i-2]
    for j in range(len(newRow)-1):
        tmp.append(str(int(newRow[j])+int(newRow[j+1])))
    tmp.append('1')
    trangle.append(tmp)
    
print_trangle(n)

题目id:48  砝码问题II

有一组砝码,重量互不相等,分别为m1、m2、m3……mn;每种砝码的数量有无限个。 
现要用这些砝码去称物体的重量,给你一个重量n,请你判断有给定的砝码能否称出重量n。 
现在给你一个正整数列表w和一个正整数n,列表w中的第i个元素w[i]表示第i种砝码的重量,
n表示要你判断的重量。如果给定砝码能称出重量n,输出Yes,否则输出No。
例如,w=[2,5,11], n=9,则输出Yes(取两个2,一个5)。

  此类问题用母函数做比较简单

def solve(): 
    num=[]
    for i in range(len(w)):
        num.append(n/w[i])
        m = set()
        for i in range(num[0]+1):
            m.add(w[0]*i)
    for i in range(1,len(num)):
        tmp = m.copy()
        m.clear()
        for j in range(num[i]+1):
            for k in tmp:
                if w[i]*j+k < n:
                    m.add(w[i]*j+k)
                elif w[i]*j+k == n:
                    return "Yes"
    return "No"

print solve()

题目id:49  进制转换

给你一个十进制数a,将它转换成b进制数,如果b>10,用大写字母表示(10用A表示,等等)
a为32位整数,2 <= b <= 16
如a=3,b = 2, 则输出11

不要忘记a为负数的情况
base = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F')
def transfer(a,b):
    res = []
    aa = abs(a)
    while aa:
        res.append(base[aa%b])
        aa/=b
    if a<0:
        res.append('-')        
    return ''.join(res[::-1])
print transfer(a,b)

 题目id:50  Py扔铅球

Py不但是编程大牛,而且是运动健将。比如说扔铅球,1000m,现在Py参加校园扔铅球比赛,
给你Py的身高a(双精度数),球落地点与Py头部的连线与水平线的夹角 b(弧度),
要你编写一个程序计算Py扔铅球的水平距离。
a,b都是浮点数,注意b是弧度,其中, 140 < a < 200,  0 < b < 1.5.
输出你求出的水平距离,保留到小数点后三位。
如,a = 165.5, b=1.1, 则输出84.234
import math
print "%.3f" % (a/math.tan(b))

 题目id:53  神の安♂排

记得有一次全班去唱K, 其中有个活动是情歌对唱. 具体操作流程是这样的:
准备好 21 个阄(我们班 15 男 6 女), 其中只有两个是有标记的, 每人随意抓取一个, 最后取到有标记的阄的两个人去点首情歌对唱.
旁边一哥们儿幽幽地对我说, 看来搅基真是神的安排啊, 你看我们班的男女人数, 搅基的几率 C(15,2)/C(21,2) 刚好是 1/2.
给跪了, 这哥们儿对数字太敏感了, 简直是拉马努金转世啊. 不过我随之想到一个问题: (21, 15) 真的是神的唯一安排吗? 其实不是的,
神还有很多类似的安排. 比如 (4, 3), 显然 C(4,2)/C(3,2) 也等于 1/2, 当然还有 (120, 85) 等等等等.
神的安排太多太多了, 如果我们定义 (n, m) 是一个安排(其中 1 < m < n), 而如果 C(m,2)/C(n,2) = 1/2, 它就是神的安排.
现在的问题是, 给你一个不大于 10^9 的正整数 N, 有多少组神的安排 (n, m) 满足 n <= N 呢?

具体参考 关于求解不定方程的n(n-1)=2m(m-1)的解法的总结
cnt = 0
x,y=1,1
while x<= 2*N-1:
    x,y=3*x+4*y,2*x+3*y
    if x > 2*N-1:
        break
    if x%2 and y%2:
        cnt +=1
print cnt

题目id:57  那些年我们集过的卡片

不知道大家的童年有没有过和我相似的经历。我记得小时候经常买干脆面,不为别的,只是因为里面有一张人物卡片。
其实有很多这样的活动都有一个相同的模式:N 种人物卡片,每次买一包干脆面随机得到一张。当你集齐这 N 种人物时,就会有相应的奖励。
那时候还不懂怎么计算概率,白白给人家送了好多钱,吃了好多干脆面。
现在的任务是,给你一个正整数 N (1 <= N <= 10^4),请你帮我从期望的角度计算平均需要买多少包干脆面才能集齐这 N 种人物。
提醒:由于结果可能不是整数,所以结果只保留到小数点后两位。
ans = 0
for i in range(N,0,-1):
        ans+=N*1.0/i
print "%.2f" % ans

 

 

 

 

 

 

 

 

 

posted @ 2013-11-09 20:52  OpenSoucre  阅读(6624)  评论(7编辑  收藏  举报