ブルーブリッジカップ2020年3月シミュレーションの質問のアイデアと回答プロセス(Pythonバージョン)
空白の質問1〜4に記入してください
質問1:コンピュータストレージに12.5MB
は何バイトありますか?
バイトとビットの違い:ビットは0または1で、中国語ではバイナリビットと呼ばれます。バイトは8ビットで、中国語の名前はバイトと呼ばれます。
12.5*1024*1024 =13107200
質問2:2019ノードを含む有向グラフには最大でいくつのエッジが含まれますか?(重複したエッジは許可されていません)
2019*2018 =4074342
それがある場合は無向グラフ、それがあります2019*2018/2 = 2037171
質問3:LANQIAOの文字を並べ替えて、異なる単語を取得します。7つの単語すべてが使用されていることに注意してください。異なる単語はいくつありますか?
7!/2 =2520
質問4:括弧のペアは合法的なシーケンスを形成できます()。2組の角かっこで2つの有効な角かっこシーケンス()()、(()を形成できます)。4つの角かっこで構成されている法定括弧シーケンスの種類はいくつですか。
找规律:
一对括号时:() count1 = 1
两对括号时:()(),(()) count2 = 1+count1 = 1+1=2
三对括号时:()()(),(())(),()(()),(()()),((((())))) count3 = 1+2*count1+count2 = 1+2+2 = 5
四对括号时:()()()(),3*(count1)()(),2*(count2)(),(count1)(count1),(count3)
count4 = 1+3+2*count2 +1+count3=14
質問5
3つの整数a、b、cが与えられ、整数がaの整数倍でも、bの整数倍でも、cの整数倍でもない場合、それは逆倍数と呼ばれます.1からnまでの逆倍数はいくつありますか? 。
[入力形式]:入力の最初の行には整数nが含まれ、2番目の行には3つの整数a、b、およびcが含まれます。スペースを使用して2つの隣接する数値を区切ります。
[出力形式]:出力行には、回答を表す整数が含まれています。
# Input:
30
2 3 6
# Output:
10
n = int(input())
a,b,c = input().split(' ')
count = 0
for i in range(1,n+1):
if not i%int(a)==0 and not i%int(b)==0 and not i%int(c)==0:
count += 1
print(count)
質問6
単語が与えられたら、シーザー暗号を使用して単語を暗号化してください。シーザー暗号は、置換暗号化技術です。アルファベットの商が3次元後方にシフトされた後、つまり、aがdに置き換えられ、zがcに置き換えられた後、単語内のすべての文字が暗号文に置き換えられます。
【入力例】:lanqiao
【出力サンプル】:odqtldr
【入力形式】:単語を1行入力すると、その単語には小文字の英字のみが含まれます。
【出力形式】:暗号化された暗号文を1行出力します
str = input()
lst = []
for i in str:
temp = ord(i)+3
if ord('d') <= temp <= ord('z'):
lst.append(chr(temp))
else:
temp = temp + ord('a')-ord('z')
lst.append(chr(temp))
final = "".join(lst)
print(final)
質問7
n行m列のテーブルの場合、スパイラルメソッドを使用してテーブルを正の整数で埋めることができ、完成したテーブルはスパイラル行列です。たとえば、4行5列のスパイラル行列は次のとおりです。
1 2 3 4 5
14 15 16 17 6
13 20 19 18 7
12 11 10 9 8
[入力形式]入力の最初の行には、スパイラル行列の行数と列数をそれぞれ表すn、mの2つの整数が含まれています。2行目には、必要な行番号と列番号を表す2つの整数r、cが含まれています。
【出力形式】スパイラル行列のr行c列の要素の値を表す整数を出力します。
# 样例输入:
4 5
2 2
# 样例输出
15
アイデア:レイヤーの数で区切ると、最も外側のレイヤーは(行数+列数-2)* 2
最初にレイヤーの数を決定し、次にどの部分が上、下、左、右にあるかを決定します。
all = input().split(' ') # str
row_all = int(all[0])
col_all = int(all[1])
target = input().split(' ') # str
r = int(target[0])
c = int(target[1])
cen = min(r-1,c-1,row_all-r,col_all-c)
num = 0
for i in range(cen):
num += (row_all+col_all-2)*2
row_all,col_all = row_all-2,col_all-2
if r-1 == cen:
num += r - cen
print(num)
elif row_all - r +cen == 0:
num += row_all + col_all - 2 +col_all+ cen - c +1
print(num)
elif c - 1 == cen:
num += 2*col_all + row_all - 2 + row_all + cen - c
print(num)
elif col_all - c + cen == 0:
num += col_all + r - cen -1
print(num)
質問8
配列の奇数番目の項目は、すべての以前のものよりも大きく、そして配列の偶数番目の項目は、すべての以前のものよりも小さく、それはある一つずつウォブルシーケンスと呼ばれるされている場合a[2i]<a[2i-1]
、a[2i+1]>a[2i]
暁長さがmで、各数値が1からnであることを知りたい正の整数のスイングシーケンスが合計でいくつありますか?
【入力形式】2つの整数m、nを含む1行を入力します
【出力形式】答えを表す整数を出力します。答えが非常に大きい場合がありますので、余りを10000で割って出力してください。
# 样例输入
3 4
# 样例输出
14
分析:質問の意味から:暴力的な解決策(列挙法):アルゴリズムの複雑さはO(n^m)
、明らかにn
合計m
が増加すると、明らかに私たちにとって問題を解決することはできません。したがって、複雑さを軽減するために、検索プロセスはすべての状況をトラバースする必要はなく、正解を解決すると考えます。
-
a[2i - 1]>a[2i]<a[2i+1]
得ることができi
たときに最初の項はi
奇数であり、それは前期よりも大きくなければならない;それは場合i
もあり、それは前期よりも小さくなければならないので、反復プロセス剪定、動的プログラミングを確立する方がよいです。 、およびこのプロセスでは、最初のn個の選択肢が計算されます。 -
したがって、最初の反復項目を初期化することをお勧めします
count[1][j] = [0, n, n-1, n-2, ...,1, 0]
。ここで、count[j]
位置は、最初の反復が。以上のj
場合に満たされるすべての条件の数です。したがって、各アイテムには次の特性があります。- すべての奇数の反復項目の場合:
count[i][j] = count[i-1][j-1]+count[i][j+1]
つまり、最初のi
反復がj
前の反復以上の場合に選択できる数(この反復は奇数であるため、偶数であるi-1
必要があります)、合計選択j-1
プラス以下のすべての回数のこの反復では、以上の回数を選択しますj+1
。 - 最初のために:すべての偶数番目の反復項目の
i
反復、選択は以上であるcount[i][j] = count[i-1][j+1]+count[i][j-1]
ことが、i
あるj
数の合計、オプション未満又は等しいの総数未満オプションまたは等しい数の合計i
より少ないオプションか等しいj-1
合計数i-1
以上のオプションに多数のオプションの第一以上に等しいオプションj+1
。 - したがって、それは場合
m
奇数である、スイングシーケンスの総数であるcount[m][1]
こと、であり、1以上の配列のすべての数を選択するために、M回を選択し、それは場合m
偶数、スイングシーケンスの総数でありますcount[m][n]
つまり、最初のシーケンス数量m
以上のシーケンスの総数m
です。
- すべての奇数の反復項目の場合:
m, n = map(int, input().split(' '))
# 初始化count二维列表
count = []
for i in range(m+2):
temp = []
for j in range(n+2):
temp.append(0)
count.append(temp[:])
for i in range(1, n+1): # 初始化第一列
count[1][i] = n-i+1
for i in range(2, m+1):
if i & 1:
for j in range(n, 0, -1):
count[i][j] = (count[i-1][j-1] + count[i][j+1]) % 10000
else:
for j in range(1, n+1):
count[i][j] = (count[i-1][j+1] + count[i][j-1]) % 10000
ans = count[m][1] if m & 1 else count[m][n]
print(ans)
注:
ブログを参照してください:
https ://qiguanjie.blog.csdn.net/article/details/105622530(質問8)質問
9〜10の詳細な説明については、Blue Bridge Cup 2020年3月のシミュレーション質問のアイデアと回答プロセス(Pythonバージョン)パート2