Blue Bridge Cup Day 17 (Python) (並べ替え + 組み合わせ)

目次

1. 知識のポイント

1. 並べ替え 

2. 組み合わせ

2. ブラッシュ質問

1.双方向ソート 

番号順 

スイスホイール

シャオランがキャンディーを食べる問題

数列評価問題

 ヤン・フイ・トライアングル

組み合わせ問題


1. 知識のポイント

1. 並べ替え 

sorted() はスライスによって部分的にソートでき、sort() 関数はリストに対してインテリジェントに使用されます。

 sorted はカスタム キーを介してカスタム ソート ルールを実装し、関数ツールをインポートする必要があります。

  -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 での組み合わせ

順列: itertools での順列

鳩の巣原理

 ヤン・フイ・トライアングル

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))

おすすめ

転載: blog.csdn.net/weixin_52261094/article/details/129842932