python编程练习(四)

一:搬圆桌

小A有一张半径为r的圆桌,其中心位于(x,y),现在他想把圆桌的中心移到(x1, y1)。每次移动一步,小A都得在圆桌边界上固定一个点,然后将圆桌绕这个点旋转。 问最少需要几步才能把圆桌移到目标位置?
分析
答案是【注意题目指的是中心,其中心位于(x,y),现在他想把圆桌的中心移到(x1, y1)】

(0,2r]-1;(2r,4r]-2;(4r,6r]-3
import math
r,x,y,x1,y1 = map(int,raw_input().split())
d = ((x1-x)**2+(y1-y)**2)**0.5
times = int(math.ceil(d / (2 * r)))
print(times)

二:投篮游戏

球场有p个篮筐,编号为0, 1, …, p-1,每个篮筐下面有个袋子,每个袋子最多能装入一个篮球。现在有n个篮球,第i个篮球有一个数字xi,投篮规则是将数字为xi的篮球,投入篮筐编号为xi除以p所得的余数。如果袋子里面已经有球,那么篮球就会弹出,投篮游戏结束,输出i;否则重复进行将篮球投完,游戏结束,输出-1。问小赛会在何时结束游戏?

p,n = map(int,raw_input().split())
b = []
for i in range(n):
    x = int(raw_input()) % p
    if x in b:
        print i+1
        break
    b.append(x)
    if i == n-1:
        print -1

三:三分线

篮球每回合根据投篮远近可以得2分或3分。如果投篮距离小于d那么得2分,大于等于d得3分。我们将d记为三分线。
第一行第一个数为n(1≤n≤2*105), 表示A队进球数,接下来n个正整数表示A队每次进球的投篮位置ai(1≤ai≤2*109)【3 1 2 3】。
第二行第一个数为m(1≤m≤2*105),表示B队进球数,接下来m个正整数表示B队每次进球的投篮位置bi(1≤bi≤2*109)【2 5 6】。
输出:一个整数,表示A队得分减去B队得分的最大值。

def score(arr,n):
    res = 0
    for i in arr:
        if i<n:
            res+=2
        else:
            res+=3
    return res
arr1 = map(int,raw_input().split())
arr2 = map(int,raw_input().split())
n,a=arr1[0],arr1[1:]
m,b=arr2[0],arr2[1:]
# n=int(raw_input())
# a=map(int,raw_input().split())
# m=int(raw_input())
# b=map(int,raw_input().split())
a.sort()
max = max(3*(n-m),2*(n-m))    # 假设都得3分或都得2分
for i in range(n):
    res1=i*2+3*(n-i)
    res2=score(b,a[i])
    if res1-res2>max:
        max=res1-res2
print max

四:聊天–参考答案,但思路明了

小明的时间表是固定的,是[a1, b1], [a2, b2], …, [ap, bp];而小红的时间表比较怪,是依赖她起床时间t的,是[c1+t, d1+t], [c2+t, d2+t], …, [cq+t, dq+t];值得注意的是,两个人时间表上的边界点也是空闲时间。小红起床时间t为[l, r]之间的任意一个整点时刻(也包括边界),只要两人能在任一时刻同时在线进行聊天,那么t就是小红合适的起床时间。询问小红能够有多少个合适的起床时间?

"""
2 3 0 20第一行数据四个整数:p,  q,  l,  r (1≤  p, q≤50, 0≤l ≤r≤1000)。
15 17
23 26
1 4
7 11
15 17
"""
p,q,l,r=map(int,raw_input().split())
a,b,c,d = [],[],[],[]
for _ in range(p):
    list1 = map(int,raw_input().split())
    a.append(list1[0])
    b.append(list1[1])
for _ in range(q):
    list2 = map(int,raw_input().split())
    c.append(list2[0])
    d.append(list2[1])
time = []
for i in range(p):
    for j in range(q):
        start = a[i] - d[j]
        end = b[i] - c[j]
        while start <= end:
            time.append(start)
            start += 1
time = set(time)
count = 0
for t in time:
    if t >= l and t <= r:
        count += 1
print count

五:Web解码

将要编码的数据拆分成字节数组,3字节为一组按顺序排列为24 位,再将24位分成每组6位的4组数据。然后在每组的最前面前补两个0位凑成一个字节。通过这种方式将3个字节的数据重新编码为4个字节。然后将这4个字节中每个字节的值作为索引通过查表的方式替换为对应的字符。查询表格中包含64个字符,依次为“0”-“9”、“+”、“-”,“a”-“z”以及“A”-“Z”。
若要编码的数据字节数不是3的整倍数,则最后一组最后填充1或2个0,并在编码完成后在结尾添加相同数目的 “=”。
现在小赛接收到编码完毕的数据,需要恢复编码前的数据。小赛发现,由于存在传输截断的可能性,并非所有接收的数据都可以解码。小赛希望你能帮忙编写程序。
分析
3个字节编码为4个字节:8x3 -> 8x4(前面加两个0) -> 对应字符x4(4个字节)【若要编码的数据字节数不是3的整倍数,则最后一组最后填充1或2个0,所以结果应该是4的倍数】
解码:四个一组,获取8位的二进制,去掉前两个

map = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
T = int(raw_input())
for _ in range(T):
    s = str(raw_input())
    if len(s)%4 !=0:
        print 'Invalid'
    else:
        n = len(s)/4
        res = ''
        for i in range(n):
            a = ''
            for ss in s[i*4:(i+1)*4]:
                if ss == '=':
                    a+='000000'
                else:
                    b = bin(map.index(ss))[2:]  # 因为前面不了两个0【bin(map.index(ss))得到的是8位】
                    c = 6 - len(b)
                    b = '0' * c + b
                    a += b
            for j in range(3):
                d = int(a[j * 8: (j + 1) * 8], 2)   # 默认是10进制,得到二进制
                if d != 0:
                    e = chr(d)
                else:
                    e = ''
                res += e
        print res

六:击鼓传花

n个同学坐着围成一个圆圈,指定一个同学手里拿着一束花,主持人在旁边背对着大家开始击鼓,鼓声开始之后拿着花的同学开始传花,每个同学都可以把花传给自己左右的两个同学中的一个(左右任意),当主持人停止击鼓时,传花停止,此时,正拿着花没传出去的那个同学就要给大家表演一个节目。有多少种不同的方法可以使得从小赛手里开始传的花,传了m次以后,又回到小赛手里。

n,m = map(int,raw_input().split())
dp = [[0 for i in range(n)] for j in range(m+1)]
dp[0][0]=1
for i in range(1,m+1):
    for j in range(n):
        dp[i][j]=dp[i-1][(j-1+n)%n] + dp[i-1][(j+1)%n]
print(dp[m][0])
"""
  0 1 2
0 1 0 0
1 0 1 1
2 2 1 1
3 2 3 3
dp[0][0]表示从0个传递0次有1中方法
dp[i][j]表示传递到j个人传了i次的方法数=传递到j个人左边传了i-1次的方法数+传递到j个人右边传了i-1次的方法数
"""

猜你喜欢

转载自blog.csdn.net/qq_27163197/article/details/80881694
今日推荐