蓝桥杯第17天(Python)(排序+组合)

目录

1.知识点

1.排序 

2.组合

2.刷题

1.双向排序 

数位排序 

瑞士轮

小蓝吃糖果问题

数列求值问题

 杨辉三角

组合数问题


1.知识点

1.排序 

sorted()可以通过切片实现部分排序,sort()函数智能用于列表上面

 sorted通过自定义key实现自定义排序规则,需要导入functools

  -1代表保持不变,1代表交换顺序。

 一个例题

import functools
def cmp(n1,n2):   # 1表示交换,-1表示不变
    if n1[1]!=n2[1]:   # 降序
        return -1 if n1[1]>n2[1] else 1
    elif n1[2] != n2[2]:  # 降序
        return -1 if n1[2]>n2[2] else 1
    else:  # 升序
        return 1 if n1[0]>n2[0] else -1
n = int(input())
scores =[]
for i in range(n):
    score = list(map(int,input().split()))
    score.append([i+1,sum(score)]+score)  # [学号,总分,语数外]
scores=sorted(iterable,key=functools.cmp_to_key(cmp))
for i in range(5):
    print(scores[i][0],scores[i][1])

2.组合

组合:itertools中的combination

排列:itertools中的permination

鸽巢原理

 杨辉三角

2.刷题

1.双向排序 

n,m=map(int,input().split())
a = [i for i in range(1,n+1)]
for i in range(m):# m次操作
    p,q=map(int,input().split())
    if p==0:
        a=sorted(a[0:q:],reverse=True)+a[q::1]  # 切片拼接  #下标从0开始,要减1
    elif p==1:
        a=a[:q-1:1]+sorted(a[q-1::1])
print(*a)

标答

n, m = map(int, input().split())
list1 = [i for i in range(1, n + 1)]
for j in range(m):

    p, q = map(int, input().split())
    if p == 0:
        list2 = list1[0:q]
        list2.sort()
        list1[0:q] = list2[::-1]
    else:
        list2 = list1[q - 1::]
        list2.sort()
        list1[q - 1::] = list2
for i in list1:
    print(i, end=' ')

超时了,过60%数据

数位排序 

import os
import sys

# 请在此输入您的代码
n = int(input())
m = int(input())
x= [str(i) for i in range(1,n+1)]

import functools
def cmp(a,b):  # -1不变 1 变
    x1=sum(list(map(int,list(a))))  # 字符串拆分转列表求和
    x2=sum(list(map(int,list(b))))
    if x1!=x2:
        return -1 if x1<x2 else 1  # 升序
    else:
        return -1 if a>b else 1   # 降序

x.sort(key=functools.cmp_to_key(cmp))
print(x[m-1])

标答

n = int(input())
m = int(input())
a = [i for i in range(1, n + 1)]
b = [0] * (n + 1)
for i in range(1, n + 1):
    #求i的数位之和
    num = i
    while num != 0:
        b[i] += num % 10
        num //= 10

a.sort(key=lambda x: (b[x], x))
print(a[m - 1])

瑞士轮

对于在该轮中全部输的人,他们之间的相对排名不会发生变化,对于在该轮中全部赢的人,也有同样的性质。

所以每次对于每轮比赛结束,只要用 O(n) 的时间复杂度就能让序列变成有序的了。


# 对于在该轮中全部输的人,他们之间的相对排名不会发生变化,对于在该轮中全部赢的人,也有同样的性质。
N, R, Q = map(int, input().split())  # 选手 ,比赛 ,名次
s = map(int, input().split()) # 初始分数
w = list(map(int, input().split()))  # 实力值
i = range(2 * N)  
data = sorted(map(lambda s, i: [s, i], s, i), key=lambda x: (-x[0], x[1]))  # 构建[分数,索引] ,按分数从大到小排序


def merge(win, lose):
    res = []
    while win and lose:
        if (win[0][0] == lose[0][0] and win[0][1] < lose[0][1]) or (
            win[0][0] > lose[0][0]
        ):  # 赢的总分高,或者总分一样但是索引更小
            res.append(win.pop(0))
        else:
            res.append(lose.pop(0))
    return res + win + lose


for _ in range(R):
    win, lose = [], []
    for i in range(0, 2 * N, 2):  # 寻找胜利者失败者
        if w[data[i][1]] > w[data[i + 1][1]]:
            data[i][0] += 1
            win.append(data[i])
            lose.append(data[i + 1])
        else:
            data[i + 1][0] += 1
            win.append(data[i + 1])
            lose.append(data[i])
    data = merge(win, lose)
print(data[Q - 1][1] + 1)

小蓝吃糖果问题

 

n = int(input())
a=list(map(int,input().split()))
if sum(a)-max(a) < max(a-1):
    # 剩下的糖果数量小于隔板弄成的空间
    #  |1|2|3|4|5|  6板最少5空间
    print('No')
else:
    print("Yes")

数列求值问题

 只要后4位,记得取余,否则内存溢出不足,就算不溢出计算也是很慢

# maxn = 20190325
# a = [0] * maxn
# a[1], a[2], a[3] = 1, 1, 1
# for i in range(4, maxn):
#     a[i] = (a[i-1] + a[i-2] + a[i-3]) % 10000
# print(a[20190324])

print(4659)

 杨辉三角

 

骗分写法(先打印出来拼接成队列,在通过列表索引找值)20%

import os
import sys

# 骗分写法
n=int(input())
a=[[1],[1,1]]
for i in range(1,50): # 50-1+2行
  b=[]
  temp=0
  for j in range(i): # 根据上一行i计算
    temp=a[i][j]+a[i][j+1]
    b.append(temp)
  a.append([1]+b+[1])
# print(a)
b=[]
for i in range(51):  #进行队列拼接
    b=b+a[i]
print(b.index(n)+1)  # 直接通过队列值找索引
 

组合数问题

 

 暴力写法,过20%

import os
import sys

# 请在此输入您的代码
def f(i,j):  # 5 3  5*4*3/3*2*1
  a,b=1,1
  for z in range(i,i-j,-1):  # 5,2
    a*=z
  for z in range(1,j+1):
    b*=z
  return a//b


t,k = map(int,input().split())
ans=0
for _ in range(t):
  n,m=map(int,input().split())
  for i in range(1,n+1):
    for j in range(0,min(i,m)+1):
      if f(i,j)%k==0:
        print(i,j)
        ans+=1
print(ans%(10**9+7))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值