[Blue Bridge CupZhenti]16日間のスプリントPython

競争はもうすぐです。私と一緒に準備したPYパーティーが、Pythonをより上手にマスターできることを願っています。 

 1.距離と(空欄に記入する質問)

問題の説明:

2つの文字間の距離は、アルファベットの位置間の距離として定義されます。たとえば、AとCの間の距離は2で、LとQの間の距離は5です。

文字列の場合、文字列内の2つの文字間の距離の合計を文字列の内部距離と呼びます。

例:ZOO 内部距離は22で、ZZとOOの間の距離は11です。

すみませんLANQIAO 、内部距離はどれくらいですか?

s=input()

ans=0
for i in range(len(s)):
    for j in range(i+1,len(s)):
        ans+=abs(ord(s[i])-ord(s[j]))
print(ans)

トピック分析:

これはアスキーコードを調べることであり、2文字のアスキーの差の絶対値は距離です 

ループトラバーサルとアキュムレーションの2つのレイヤーは


2.拡散 

この質問は空欄を埋める質問です。結果を計算した後、コードのoutputステートメントを使用して、埋められた結果を出力します。

Xiao Lanは、無限のサイズの特別なキャンバスにペイントします。

このキャンバスはグリッドとして見ることができ、各グリッドは2次元の整数座標で表すことができます。

Xiaolanは最初にキャンバス上のいくつかのポイントをクリックしました:(0、0)、(2020、11)、(11、14)、(2000、2000)

これらのグリッドのみが黒で、残りは白です。

1分が経過するごとに、黒が少し広がります。具体的には、グリッドが黒の場合、隣接する4つのグリッドの上、下、左、右に広がり、これらの4つのグリッドも黒になります(元々黒だった場合は、まだ黒です)。

すみません、2020分後、キャンバス上で黒のグリッドがいくつありますか。

トピック分析:

マルチソースBFSを調査するために、ACwingシミュレーション競争の農地灌漑問題から学ぶことができます。同じように、私はこのブログに詳細な分析を書きました:[Blue Bridge CupZhenti]18日間のPythonチームスプリント体験summary_PyXiaozhengのブログ-CSDNブログ

ただし、この質問の場合、PYパートナーが通常のリストを使用してキューをシミュレートすると、実行できなくなり、速度が遅くなります。

リストの削除と挿入の複雑さはO(n)であるため、データ量は多くなります。

PYに付属のライブラリでdeque(双方向キュー)を使用する必要があります。時間計算量はO(1)であり、30分でなくなる可能性があります。

この質問に合格するための最も重要なことは、速度を向上させるためにdequeを使用する方法を学ぶことです。

collections.deque学習ポータル: Pythonコレクションモジュールのdeque()の詳細な説明-プログラマーが求めた

import collections

dx=[-1,1,0,0]
dy=[0,0,1,-1]

pre={(0,0):(0,0),(2020, 11):(2020,11),(11, 14):(11, 14),(2000, 2000):(2000, 2000)}
ans=4
queue=collections.deque()
queue.append((0,0,0))
queue.append((2020, 11, 0))
queue.append((11, 14, 0))
queue.append((2000, 2000, 0))

while queue:
    t=queue.popleft()
    if t[2]==2020:
        print(ans)
        break
    else:
        for i in range(4):
            nx,ny=t[0]+dx[i],t[1]+dy[i]
            if (nx,ny) not in pre.keys():
                pre[(nx,ny)]=(t[0],t[1])
                queue.append((nx,ny,t[2]+1))
                ans+=1
#扩散 20312088
                

3.間違ったチケット 

あなたは私の記事の最初の質問を見ることができます 

ブルーブリッジカップ準備練習Pythonインパクト州1-PyXiaozhengのブログ-CSDNブログ

4.複数の問題

ご存知のように、シャオタマネギは計算が得意で、特にある数が別の数の倍数であるかどうかを計算するのが得意です。しかし、エシャロットは2つの数字しか得意ではなく、数字が多いと、より苦しむことになります。これでタマネギはあなたにn個の数を与えました、そしてあなたがこれらのn個の数から3つの数を見つけることができるといいのですが、これらの3つの数の合計はKの倍数であり、この合計が最大です。データは、解決策が必要であることを保証します。

説明を入力してください

最初の行には、2つの正の整数n、Kが含まれています。

2行目には、指定されたn個の数値を表すn個の正の整数が含まれています。

出力の説明

1行の出力は、目的の合計を表す整数です。

トピック分析: 

Xiao Zhengも長い間それを研究していて、彼は前回それを解決しなかったので、この質問はよく説明される必要があります...

ここで私の良い兄弟に感謝します

 ブルーブリッジ複数問題列挙の最適化

私は彼から多くの私の考えを学びました、それで以下の分析の多くは彼の元の言葉を引用します(彼はとても上手に話すので!)

まず、暴力的な方法である3層のforループをタイムアウトする必要があります。これは、方法を変更する必要があることを示しています。

x + y + z = nk(x、y、z、n、k> 0)とすると、

(x%k + y%k + z%k)%k = 0(アルゴリズムに従って取得

問題は、元のn個の数が集合Aを形成することを知って、次のように変換されます。次に、各数の残りを取り、新しい集合Bを形成します。集合Bでは、合計がkの倍になるように3つの要素を取ります。セットAの対応する要素が追加され、合計が最大になります。

辞書dic[i]= [x、y、z ...]を設定することもできます:数値x、y、zを表します。kの余りをとった結果はiです。

常に大きな数字を取りたいので、セットAを降順(大きいものから小さいものへ)に並べ替えて、残りのすべての数字を辞書に入れ、各キーに対応するリストを次のようにすることもできます。大から小へ。

n,k=map(int,input().split())

a=list(map(int,input().split()))
a.sort(reverse=True)
b=dict()

for i in range(len(a)):
    r=a[i]%k
    if r not in b.keys():
        b[r]=[a[i]]
    else:
        b[r].append(a[i])

答えをansに設定します。初期値は0です。次のステップは、余りの組み合わせを見つけ(合計がkの倍数である場合)、ansを更新することです。

最初の2つの剰余i、jを列挙すると、3番目の剰余tは一意に決定され、3層のループは必要ありません(ループオプティマイザーを可能な限り減らします)

その理由は次のとおりです。i、j、tがkの剰余をとって得られる集合Aのすべての要素である場合、i、j、tはすべて範囲(0、k)を満たす必要があります。

次に、i + j + tは範囲(0,3k)を満たす必要があり、i + j + t=kまたは2kは質問の意味と一致します

そして、i + jは範囲(0,2k)を満たし、2k> i + j> kの場合、t = 2k-ij、

0 <i + j <k、t = kijの場合、i、jのセットに対して、i + jの範囲が決定されるため、 3番目の剰余tが一意に決定されます。

for i in range(k):
    for j in range(k):
        t = k-i-j if (i+j)<= k else 2*k-i-j

次に、ansを更新します。

3つの剰余については、3つ以下のケースがあり、3つの剰余は同じであり、2つの剰余は同じであり、1つの剰余は同じです(相互に異なる)

3つの剰余が同じで、剰余に対応するリストの長さ(要素の数)が3以上の場合、それは実行可能な解決策です。そうでない場合、3つの数を構成できないため、解決策はありません。

2つの剰余が同じで、この剰余に対応するリストの長さ(要素の数)が3以上で、3番目の剰余に対応するリストの長さ(要素の数)が(これら2つとは異なる)場合> = 1(つまり、空ではない)の場合、それは実行可能な解決策です。そうでない場合、解決策はありません。

残りの1つが同じである場合、3つの相互に異なる残りに対応するリストが空でない限り、実行可能な解決策があります。

次に、ansを実行可能なソリューションと比較し続けると、ansは常に更新されて大きくなります。実際、2つの余りが同じ場合、12、13、23になる可能性があるため、3つのタイプに分けることができます。

for i in range(k):
    for j in range(k):
        t = k-i-j if (i+j)<= k else 2*k-i-j
        if i==j==t:
            if len(b[t])>=3:
                ans=max(ans,b[t][0]+b[t][1]+b[t][2])
        elif i==j:
            if len(b[i])>=2 and len(b[t])>=1:
                ans=max(ans,b[i][0]+b[i][1]+b[t][0])
        elif i==t:
            if len(b[i])>=2 and len(b[j])>=1:
                ans=max(ans,b[i][0]+b[i][1]+b[j][0])
        elif j==t:
            if len(b[j])>=2 and len(b[i])>=1:
                ans=max(ans,b[j][0]+b[j][1]+b[i][0])
        else:#三个互异
            if len(b[i])>=1 and len(b[j])>=1and len(b[t])>=1:
                ans=max(ans,b[i][0]+b[j][0]+b[t][0])

 キーが存在しないため、キーエラーが報告されます。したがって、残りがbにない場合は、次のサイクルを直接実行できます。

for i in range(k):
    for j in range(k):
        t = k-i-j if (i+j)<= k else 2*k-i-j
        if i not in b or j not in b or t not in b:
            continue
        if i==j==t:
            if len(b[t])>=3:
                ans=max(ans,b[t][0]+b[t][1]+b[t][2])
        elif i==j:
            if len(b[i])>=2:
                ans=max(ans,b[i][0]+b[i][1]+b[t][0])
        elif i==t:
            if len(b[i])>=2:
                ans=max(ans,b[i][0]+b[i][1]+b[j][0])
        elif j==t:
            if len(b[j])>=2:
                ans=max(ans,b[j][0]+b[j][1]+b[i][0])
        else:#三个互异
            ans=max(ans,b[i][0]+b[j][0]+b[t][0])

コードを要約するには

n,k=map(int,input().split())

a=list(map(int,input().split()))
a.sort(reverse=True)
b=dict()

for i in range(len(a)):
    r=a[i]%k
    if r not in b.keys():
        b[r]=[a[i]]
    else:
        b[r].append(a[i])

ans=0

for i in range(k):
    for j in range(k):
        t = k-i-j if (i+j)<= k else 2*k-i-j
        if i not in b or j not in b or t not in b:
            continue
        if i==j==t:
            if len(b[t])>=3:
                ans=max(ans,b[t][0]+b[t][1]+b[t][2])
        elif i==j:
            if len(b[i])>=2:
                ans=max(ans,b[i][0]+b[i][1]+b[t][0])
        elif i==t:
            if len(b[i])>=2:
                ans=max(ans,b[i][0]+b[i][1]+b[j][0])
        elif j==t:
            if len(b[j])>=2:
                ans=max(ans,b[j][0]+b[j][1]+b[i][0])
        else:#三个互异
            ans=max(ans,b[i][0]+b[j][0]+b[t][0])
print(ans)

お役に立てば、3年連続で大丈夫ですか!

ご不明な点がございましたら、コメント欄でお尋ねください!! 

おすすめ

転載: blog.csdn.net/m0_62277756/article/details/123701617